Desde uma análise mais geral, até uma análise mais minuciosa sobre o ENEM 2019 você irá encontrar aqui!
Gráficos, scripts e relatórios sobre as minhas conclusões como Atuário e Cientista de Dados, estarão disponíveis nas diversas seções. Procurei explorar ao máximo correlações e indicadores que possam elucidar algum tipo de comportamento nas notas e nos candidatos do ENEM de 2019. Utilizei uma amostra considerável, disponibilizada pela Alura.

Bibliotecas
import os
import requests
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
import folium
from folium import plugins
import json
import statsmodels.api as sm
from statsmodels.formula.api import ols
from statsmodels.stats.multicomp import MultiComparison
from sklearn.model_selection import train_test_split
/usr/local/lib/python3.6/dist-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead. import pandas.util.testing as tm
#Coletando a fonte dos dados
font = "https://github.com/alura-cursos/imersao-dados-2-2020/blob/master/MICRODADOS_ENEM_2019_SAMPLE_43278.csv?raw=true"
#Utilizando o pandas para ler o arquivo csv
dados_enem2019 = pd.read_csv(font)
#Visualizando as 5 primeiras linhas dos dados carregados
dados_enem2019.head()
| NU_INSCRICAO | NU_ANO | CO_MUNICIPIO_RESIDENCIA | NO_MUNICIPIO_RESIDENCIA | CO_UF_RESIDENCIA | SG_UF_RESIDENCIA | NU_IDADE | TP_SEXO | TP_ESTADO_CIVIL | TP_COR_RACA | TP_NACIONALIDADE | CO_MUNICIPIO_NASCIMENTO | NO_MUNICIPIO_NASCIMENTO | CO_UF_NASCIMENTO | SG_UF_NASCIMENTO | TP_ST_CONCLUSAO | TP_ANO_CONCLUIU | TP_ESCOLA | TP_ENSINO | IN_TREINEIRO | CO_ESCOLA | CO_MUNICIPIO_ESC | NO_MUNICIPIO_ESC | CO_UF_ESC | SG_UF_ESC | TP_DEPENDENCIA_ADM_ESC | TP_LOCALIZACAO_ESC | TP_SIT_FUNC_ESC | IN_BAIXA_VISAO | IN_CEGUEIRA | IN_SURDEZ | IN_DEFICIENCIA_AUDITIVA | IN_SURDO_CEGUEIRA | IN_DEFICIENCIA_FISICA | IN_DEFICIENCIA_MENTAL | IN_DEFICIT_ATENCAO | IN_DISLEXIA | IN_DISCALCULIA | IN_AUTISMO | IN_VISAO_MONOCULAR | ... | TX_RESPOSTAS_CH | TX_RESPOSTAS_LC | TX_RESPOSTAS_MT | TP_LINGUA | TX_GABARITO_CN | TX_GABARITO_CH | TX_GABARITO_LC | TX_GABARITO_MT | TP_STATUS_REDACAO | NU_NOTA_COMP1 | NU_NOTA_COMP2 | NU_NOTA_COMP3 | NU_NOTA_COMP4 | NU_NOTA_COMP5 | NU_NOTA_REDACAO | Q001 | Q002 | Q003 | Q004 | Q005 | Q006 | Q007 | Q008 | Q009 | Q010 | Q011 | Q012 | Q013 | Q014 | Q015 | Q016 | Q017 | Q018 | Q019 | Q020 | Q021 | Q022 | Q023 | Q024 | Q025 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 190001004661 | 2019 | 1506138 | Redenção | 15 | PA | 17 | M | 1 | 3 | 1 | 1506138.0 | Redenção | 15.0 | PA | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | ACAEAAACABEBABAADCEEEDE*CBDCCCADADCCCBEBBBBDB | 99999CCCABBCAADDBCEBCCADBEEBDECBAABDEACACAEABB... | DEEDCAECDDEEECBCBECABEBAECBBCDAECAEBBBBBDCCDB | 1 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 60.0 | 100.0 | 80.0 | 80.0 | 100.0 | 420.0 | B | B | A | A | 4 | B | A | C | B | A | C | B | A | A | A | A | A | A | A | B | A | C | A | B | B |
| 1 | 190001004674 | 2019 | 1504208 | Marabá | 15 | PA | 23 | M | 1 | 3 | 1 | 1504208.0 | Marabá | 15.0 | PA | 1 | 3 | 1 | 1.0 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | ABBCEADCEBAAACACEDCDCDACCCACDCBCABCAACBDBDEDE | 99999ABCEBCEDDECEEEBBCCEECCABDABEEBCDEAEBBEAEA... | NaN | 1 | NaN | CBABADBBCEEEBCBADCBEEDBBEADBBACDBBACCCCADACAC | BBEDABDACACBABAECBBCCADCEBDBBCDDEEAAADDBECDECA... | NaN | 1.0 | 80.0 | 100.0 | 80.0 | 80.0 | 60.0 | 400.0 | C | C | A | A | 4 | B | A | B | C | A | A | B | B | B | A | A | A | A | B | A | A | B | A | A | B |
| 2 | 190001004722 | 2019 | 1501402 | Belém | 15 | PA | 35 | F | 2 | 1 | 1 | 1501402.0 | Belém | 15.0 | PA | 1 | 12 | 1 | 1.0 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | CDCAACCAAADEACBBEBAAEECDABDEBAEAABEDCABABAABC | 99999ECBCECEBBABECCCECECCEECCDECEEEDADDDDECEDD... | DDBEADEBBCADCEEACABECBCEBADECADCEDAACBDABABCE | 1 | AAECACDEADCBCDDDBCBDADAEABCEBABEEBCBEECEBDADC | CBABADBBCEEEBCBADCBEEDBBEADBBACDBBACCCCADACAC | BBEDABDACACBABAECBBCCADCEBDBBCDDEEAAADDBECDECA... | EEEADBEBACABCDBABECECACDCBDCCEDCDABEDECDDDBAA | 1.0 | 100.0 | 120.0 | 120.0 | 100.0 | 120.0 | 560.0 | C | A | B | B | 5 | C | A | B | C | A | A | B | A | B | A | A | A | A | B | A | B | B | A | A | B |
| 3 | 190001004735 | 2019 | 1507300 | São Félix do Xingu | 15 | PA | 23 | F | 1 | 3 | 1 | 1505437.0 | Ourilândia do Norte | 15.0 | PA | 1 | 7 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | EECCCEDBADBEAAAAEBAECEAAAAEEEBACCAC*CEAEDAECE | 99999BABCDABBCBDDAAECADBDDADDCBCEEDCAEBCEAEABD... | CBDEBBCBDEBCABCDBDEDADCCBEDBCAECEBEBDEBAEECBC | 1 | BEEAAEBEEBADEADDADAEABCEDDDBCBCBCCACBCDADCCEB | EEBCEEDBADBBCBABCCADCEBACDBBACCACACBEADBBADCB | ADBBEDCABAABBCBCDAAECDDDBAAAECADECDCEBDEEAECBD... | BEDEEEAADBEBACABCDBABECECACADCBDCCEDCDABECDDD | 1.0 | 100.0 | 120.0 | 120.0 | 120.0 | 40.0 | 500.0 | E | C | A | A | 1 | B | A | B | C | A | A | B | A | A | A | A | A | A | B | A | A | B | A | A | B |
| 4 | 190001004776 | 2019 | 1500800 | Ananindeua | 15 | PA | 16 | F | 1 | 3 | 1 | 1500800.0 | Ananindeua | 15.0 | PA | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | CCBCBEACABACABBBBACCBCEBDCBABCADADCBCADBAADEA | EBCAB99999BBCECBCACBEACBDAABDBCBBDACEBBACDCAEC... | AECCBBCBBCBDEDECACBAABEDABBEDDADCEADDBEBDBBEB | 0 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 160.0 | 140.0 | 160.0 | 160.0 | 160.0 | 780.0 | E | E | B | D | 3 | E | A | B | C | B | A | B | A | A | A | A | A | A | B | A | A | D | A | A | B |
5 rows × 136 columns
dados_enem2019.shape #Visualizando o tamanho dos dados
(127380, 136)
Primordialmente, os dados foram carregados corretamente, contendo 136 variáveis para serem analisadas, cada uma com um fim e uma possível correlação com outra.
Para esta ocasião, estarei observando o dataset como um todo. Irei verificar a distribuição das idades, o que significa os valores NaN.
A idade do candidado pode ser explorada pela variável NU_IDADE, portanto, criarei gráficos e dataframes baseados nela.
idades_enem_2019 = dados_enem2019['NU_IDADE'] #Coletando a série
pd.DataFrame(idades_enem_2019.value_counts(normalize = True)) #Verificando a proporção, do maior para o menor
| NU_IDADE | |
|---|---|
| 18 | 0.168409 |
| 17 | 0.166871 |
| 19 | 0.113189 |
| 20 | 0.081748 |
| 16 | 0.061470 |
| ... | ... |
| 75 | 0.000016 |
| 73 | 0.000016 |
| 82 | 0.000008 |
| 77 | 0.000008 |
| 76 | 0.000008 |
65 rows × 1 columns
A idade com maior frequência nos dados da amostra foi de candidatos com 18 anos.
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
enem_media_idades = plt.axvline(x = idades_enem_2019.mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_idades = plt.axvline(x = idades_enem_2019.median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_idades = plt.axvline(x = idades_enem_2019.mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_idades, enem_mediana_idades, enem_moda_idades], ['Média', 'Mediana', 'Moda'])
sns.histplot(idades_enem_2019, bins = 35).set_title('Distribuição das Idades ENEM-2019', fontsize = 16);
A partir do grafico acima, é visível que a concentração de dados está por volta dos candidatos entre 17 e 25 anos. Ressalto que o mesmo gráfico se assemelha a uma Distribuição de Poisson.
pd.DataFrame(idades_enem_2019.describe()) #Análise descritiva
| NU_IDADE | |
|---|---|
| count | 127380.000000 |
| mean | 22.094355 |
| std | 7.498707 |
| min | 13.000000 |
| 25% | 18.000000 |
| 50% | 19.000000 |
| 75% | 24.000000 |
| max | 82.000000 |
A média de idade, na amostra, é de aproximadamente 22 anos. Entretanto, a mediana é de 19 anos. É possível visualizar que, apesar da idade máxima ser 82 anos, o terceiro quartil está em 24 anos de idade, sendo assim, ao menos 75% dos candidados tinham 24 anos ou menos. Conclui-se, também, que as idades NÃO estão normalmente distribuídas.
media_idade_municipio = pd.DataFrame(dados_enem2019.groupby(['NO_MUNICIPIO_RESIDENCIA']).mean()['NU_IDADE'])
media_idade_municipio.loc[media_idade_municipio['NU_IDADE'] == media_idade_municipio['NU_IDADE'].max()] #O Município com a média mais alta
| NU_IDADE | |
|---|---|
| NO_MUNICIPIO_RESIDENCIA | |
| Lagoa dos Patos | 50.0 |
media_idade_municipio.loc[media_idade_municipio['NU_IDADE'] == media_idade_municipio['NU_IDADE'].min()] #O Município com a média mais baixa
| NU_IDADE | |
|---|---|
| NO_MUNICIPIO_RESIDENCIA | |
| Grupiara | 14.0 |
municipio_idade = media_idade_municipio.index
media_idade_municipio['Cidade'] = municipio_idade
media_idade_municipio.head()
| NU_IDADE | Cidade | |
|---|---|---|
| NO_MUNICIPIO_RESIDENCIA | ||
| Abadia de Goiás | 22.928571 | Abadia de Goiás |
| Abadia dos Dourados | 20.875000 | Abadia dos Dourados |
| Abadiânia | 19.181818 | Abadiânia |
| Abaetetuba | 23.587879 | Abaetetuba |
| Abaeté | 21.769231 | Abaeté |
Importarei um dataset que analisa a longitude e latidude de cada município a fim de gerar um gráfico cartográfico
site = 'https://github.com/kelvins/Municipios-Brasileiros/blob/main/csv/municipios.csv?raw=true'
coordenadas = pd.read_csv(site)
concatenado_idade = pd.merge(media_idade_municipio, coordenadas, how = 'left', left_on=['Cidade'], right_on = ['nome'])
concatenado_idade.plot.scatter(y='latitude', x = 'longitude',
c = concatenado_idade['NU_IDADE'],
cmap = 'PiYG',
figsize = (12,10)).set_title('Média de Idade ENEM 2019 por Município', fontsize = 16);
No gráfico acima, visualiza-se que a região mais escura (de acordo com a escala) tende à região Sul/Sudeste. Em contrapartida, o nordeste se apresenta levemente com uma cor mais clara. Isso ressalta que, as regiões mais ao Sul do país apresentam idades mais novas em candidatos no ENEM 2019.
Levanto a hipótese de uma possível política de incentivo maior às crianças e aos secundaristas.
Qual estado predomina com candidatos mais novos?
novos_idade_enem2019 = dados_enem2019.query('NU_IDADE <= 17')
prop_novos_idade_enem2019 = pd.DataFrame(novos_idade_enem2019['SG_UF_RESIDENCIA'].value_counts(normalize = True)*100)
#Plotando o gráfico com a escala da proporção
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
ax = sns.barplot(x=prop_novos_idade_enem2019.index, y = prop_novos_idade_enem2019['SG_UF_RESIDENCIA'], data=prop_novos_idade_enem2019).set_title('Proporção de candidatos com Idade menor que 17 por Estado', fontsize = 16)
O Estado com candidatos mais jovens foi o de São Paulo. Em sequência, segue o estado de Minas Gerais. Esse atributo pode reforçar o mapa anterior proposto, demonstrando o escurecimento na região Sudeste e Sul.
Esta pergunta pode ser respondida pela seguinte análise:
dados_enem2019.loc[dados_enem2019['NU_IDADE'] == dados_enem2019['NU_IDADE'].max()]
| NU_INSCRICAO | NU_ANO | CO_MUNICIPIO_RESIDENCIA | NO_MUNICIPIO_RESIDENCIA | CO_UF_RESIDENCIA | SG_UF_RESIDENCIA | NU_IDADE | TP_SEXO | TP_ESTADO_CIVIL | TP_COR_RACA | TP_NACIONALIDADE | CO_MUNICIPIO_NASCIMENTO | NO_MUNICIPIO_NASCIMENTO | CO_UF_NASCIMENTO | SG_UF_NASCIMENTO | TP_ST_CONCLUSAO | TP_ANO_CONCLUIU | TP_ESCOLA | TP_ENSINO | IN_TREINEIRO | CO_ESCOLA | CO_MUNICIPIO_ESC | NO_MUNICIPIO_ESC | CO_UF_ESC | SG_UF_ESC | TP_DEPENDENCIA_ADM_ESC | TP_LOCALIZACAO_ESC | TP_SIT_FUNC_ESC | IN_BAIXA_VISAO | IN_CEGUEIRA | IN_SURDEZ | IN_DEFICIENCIA_AUDITIVA | IN_SURDO_CEGUEIRA | IN_DEFICIENCIA_FISICA | IN_DEFICIENCIA_MENTAL | IN_DEFICIT_ATENCAO | IN_DISLEXIA | IN_DISCALCULIA | IN_AUTISMO | IN_VISAO_MONOCULAR | ... | TX_RESPOSTAS_CH | TX_RESPOSTAS_LC | TX_RESPOSTAS_MT | TP_LINGUA | TX_GABARITO_CN | TX_GABARITO_CH | TX_GABARITO_LC | TX_GABARITO_MT | TP_STATUS_REDACAO | NU_NOTA_COMP1 | NU_NOTA_COMP2 | NU_NOTA_COMP3 | NU_NOTA_COMP4 | NU_NOTA_COMP5 | NU_NOTA_REDACAO | Q001 | Q002 | Q003 | Q004 | Q005 | Q006 | Q007 | Q008 | Q009 | Q010 | Q011 | Q012 | Q013 | Q014 | Q015 | Q016 | Q017 | Q018 | Q019 | Q020 | Q021 | Q022 | Q023 | Q024 | Q025 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 85002 | 190004396266 | 2019 | 3303302 | Niterói | 33 | RJ | 82 | F | 4 | 1 | 1 | 3303302.0 | Niterói | 33.0 | RJ | 1 | 13 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | NaN | NaN | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | F | B | E | C | 2 | P | B | C | D | A | A | B | B | B | A | B | A | A | D | B | B | D | B | C | B |
1 rows × 136 columns
O candidato mais idoso da amostra tinha 82 anos e residia em Niterói.
dados_enem2019.loc[dados_enem2019['NU_IDADE'] == dados_enem2019['NU_IDADE'].min()]
| NU_INSCRICAO | NU_ANO | CO_MUNICIPIO_RESIDENCIA | NO_MUNICIPIO_RESIDENCIA | CO_UF_RESIDENCIA | SG_UF_RESIDENCIA | NU_IDADE | TP_SEXO | TP_ESTADO_CIVIL | TP_COR_RACA | TP_NACIONALIDADE | CO_MUNICIPIO_NASCIMENTO | NO_MUNICIPIO_NASCIMENTO | CO_UF_NASCIMENTO | SG_UF_NASCIMENTO | TP_ST_CONCLUSAO | TP_ANO_CONCLUIU | TP_ESCOLA | TP_ENSINO | IN_TREINEIRO | CO_ESCOLA | CO_MUNICIPIO_ESC | NO_MUNICIPIO_ESC | CO_UF_ESC | SG_UF_ESC | TP_DEPENDENCIA_ADM_ESC | TP_LOCALIZACAO_ESC | TP_SIT_FUNC_ESC | IN_BAIXA_VISAO | IN_CEGUEIRA | IN_SURDEZ | IN_DEFICIENCIA_AUDITIVA | IN_SURDO_CEGUEIRA | IN_DEFICIENCIA_FISICA | IN_DEFICIENCIA_MENTAL | IN_DEFICIT_ATENCAO | IN_DISLEXIA | IN_DISCALCULIA | IN_AUTISMO | IN_VISAO_MONOCULAR | ... | TX_RESPOSTAS_CH | TX_RESPOSTAS_LC | TX_RESPOSTAS_MT | TP_LINGUA | TX_GABARITO_CN | TX_GABARITO_CH | TX_GABARITO_LC | TX_GABARITO_MT | TP_STATUS_REDACAO | NU_NOTA_COMP1 | NU_NOTA_COMP2 | NU_NOTA_COMP3 | NU_NOTA_COMP4 | NU_NOTA_COMP5 | NU_NOTA_REDACAO | Q001 | Q002 | Q003 | Q004 | Q005 | Q006 | Q007 | Q008 | Q009 | Q010 | Q011 | Q012 | Q013 | Q014 | Q015 | Q016 | Q017 | Q018 | Q019 | Q020 | Q021 | Q022 | Q023 | Q024 | Q025 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 57359 | 190003297248 | 2019 | 3504107 | Atibaia | 35 | SP | 13 | F | 1 | 1 | 1 | 3556701.0 | Vinhedo | 35.0 | SP | 4 | 0 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | CAEBCEBECAABCDBEEAEDDBCBACBCECAABDCACEABAEADC | BAAEC99999BCCDDEDACBAADECADBEADBADDBECADEBCBDA... | AABDCEACDDBEDABDDACBDECABACDDBAECDBECBBDEBCDA | 0 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 160.0 | 200.0 | 200.0 | 200.0 | 160.0 | 920.0 | E | G | C | D | 3 | F | A | C | C | B | A | B | B | B | A | B | A | A | B | A | A | D | B | B | B |
| 95630 | 190004825557 | 2019 | 5107602 | Rondonópolis | 51 | MT | 13 | M | 1 | 1 | 1 | 5107602.0 | Rondonópolis | 51.0 | MT | 4 | 0 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | NaN | NaN | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | E | E | C | D | 3 | F | A | B | C | B | A | B | A | A | A | A | A | A | B | B | A | B | A | A | B |
| 98197 | 190004926952 | 2019 | 1600303 | Macapá | 16 | AP | 13 | M | 1 | 3 | 1 | 1600303.0 | Macapá | 16.0 | AP | 4 | 0 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | NaN | NaN | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | G | E | D | B | 4 | K | B | C | D | B | A | B | B | B | B | B | A | A | C | B | A | E | A | B | B |
| 116501 | 190005659236 | 2019 | 2917508 | Jacobina | 29 | BA | 13 | M | 1 | 3 | 1 | 2304400.0 | Fortaleza | 23.0 | CE | 4 | 0 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | ADCCCCDCEAAABCEEEDAD*CCCDEBADCDBBBCBEBDBDBECC | EBBAD99999BDCBCCBCEBBCADEDDEDECDECDECECACDCECC... | ECEADDBBABCCCDBDCAAECABDCBDBCECCECABCABBBCBAA | 0 | AAECACDEADCBCDDDBCBDADAEABCEBABEEBCBEECEBDADC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | EEEADBEBACABCDBABECECACDCBDCCEDCDABEDECDDDBAA | 1.0 | 100.0 | 120.0 | 100.0 | 80.0 | 100.0 | 500.0 | D | F | D | B | 4 | D | A | E | E | C | A | B | A | B | A | B | A | A | D | A | B | C | B | C | B |
4 rows × 136 columns
Os candidados mais novos da amostra continham 13 anos de idade e residiam em três estados diferentes: São Paulo, Mato Grosso, Amapá e Bahia.
De fato, todo e qualquer dataset está submetivo à conter valores faltantes. Será que o dataset da amostra obtém dados faltantes?
provas = ['NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC']
dados_enem2019[provas].isna().head()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | |
|---|---|---|---|---|
| 0 | False | False | False | False |
| 1 | True | False | True | False |
| 2 | False | False | False | False |
| 3 | False | False | False | False |
| 4 | False | False | False | False |
É possível visualizar que, há valores faltantes apenas pela aparição do True no dataset acima. Por que eles aparecem?
dados_faltantes_notas = dados_enem2019[['NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC', 'TP_PRESENCA_CN', 'TP_PRESENCA_CH', 'TP_PRESENCA_MT', 'TP_PRESENCA_LC']]
dados_faltantes_notas.head()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | TP_PRESENCA_CN | TP_PRESENCA_CH | TP_PRESENCA_MT | TP_PRESENCA_LC | |
|---|---|---|---|---|---|---|---|---|
| 0 | 435.6 | 512.3 | 432.4 | 488.6 | 1 | 1 | 1 | 1 |
| 1 | NaN | 409.3 | NaN | 375.3 | 0 | 1 | 0 | 1 |
| 2 | 423.2 | 499.1 | 427.2 | 441.0 | 1 | 1 | 1 | 1 |
| 3 | 426.2 | 578.1 | 499.9 | 551.5 | 1 | 1 | 1 | 1 |
| 4 | 516.5 | 571.3 | 424.5 | 511.2 | 1 | 1 | 1 | 1 |
A partir da tabela acima, com o índice igual a 1, é possível relacionar com as faltas dos candidatos nos dias das provas que correspondem aos valores NaN.
O sexo declarado pelo candidado pode ser explorado pela variável TP_SEXO, portanto, criarei gráficos e dataframes baseados nela.
sexos_enem_2019 = dados_enem2019['TP_SEXO'] #Coletando a série
sexos_enem_2019 = pd.DataFrame(sexos_enem_2019.value_counts(normalize = True)) #Verificando a proporção, do maior para o menor
sexos_enem_2019
| TP_SEXO | |
|---|---|
| F | 0.595721 |
| M | 0.404279 |
É nítido que, aproximadamente 60% dos candidatos da amostra do ENEM 2019 são do sexo Feminino.
plt.style.use('seaborn')
sexos_enem_2019.plot.pie(y='TP_SEXO', figsize=(5, 5)).set_title('Distribuição dos Sexos ENEM-2019', fontsize = 16);
dist_sexo_por_municipio = pd.crosstab(dados_enem2019.NO_MUNICIPIO_RESIDENCIA, dados_enem2019.TP_SEXO)
dist_sexo_por_municipio['Feminino maior'] = dist_sexo_por_municipio['F'] > dist_sexo_por_municipio['M']
municipio_sexo = dist_sexo_por_municipio.index
dist_sexo_por_municipio['Cidade'] = municipio_sexo
dist_sexo_por_municipio.head()
| TP_SEXO | F | M | Feminino maior | Cidade |
|---|---|---|---|---|
| NO_MUNICIPIO_RESIDENCIA | ||||
| Abadia de Goiás | 8 | 6 | True | Abadia de Goiás |
| Abadia dos Dourados | 3 | 5 | False | Abadia dos Dourados |
| Abadiânia | 4 | 7 | False | Abadiânia |
| Abaetetuba | 106 | 59 | True | Abaetetuba |
| Abaeté | 8 | 5 | True | Abaeté |
concatenado_sexo = pd.merge(dist_sexo_por_municipio, coordenadas, how = 'left', left_on=['Cidade'], right_on = ['nome'])
concatenado_sexo.plot.scatter(y='latitude', x = 'longitude',
c = concatenado_sexo['Feminino maior'],
cmap = 'coolwarm',
figsize = (12,10)).set_title('Municípios distribuídos pela maioria do sexo em candidatos ENEM2019', fontsize = 16);
plt.text(0, 0, 'Vermelho = Feminino / Azul = Masculino', va = 'center',
size=30, alpha=.5);
Percebe-se que, a grande maioria dos municípios possui maior participação de pessoas com sexo feminino do que sexo masculino
Quem tirou acima de 600 em todas as provas, é de qual sexo?
Essa pergunta pode ser respondida pela filtração dos candidados com notas maiores que 600 e, consequentemente, realizando a frequência de cada sexo.
alunos_acima = dados_enem2019.query('NU_NOTA_CN > 600 & NU_NOTA_CH > 600 & NU_NOTA_MT > 600 & NU_NOTA_LC > 600')
alunos_acima.head()
| NU_INSCRICAO | NU_ANO | CO_MUNICIPIO_RESIDENCIA | NO_MUNICIPIO_RESIDENCIA | CO_UF_RESIDENCIA | SG_UF_RESIDENCIA | NU_IDADE | TP_SEXO | TP_ESTADO_CIVIL | TP_COR_RACA | TP_NACIONALIDADE | CO_MUNICIPIO_NASCIMENTO | NO_MUNICIPIO_NASCIMENTO | CO_UF_NASCIMENTO | SG_UF_NASCIMENTO | TP_ST_CONCLUSAO | TP_ANO_CONCLUIU | TP_ESCOLA | TP_ENSINO | IN_TREINEIRO | CO_ESCOLA | CO_MUNICIPIO_ESC | NO_MUNICIPIO_ESC | CO_UF_ESC | SG_UF_ESC | TP_DEPENDENCIA_ADM_ESC | TP_LOCALIZACAO_ESC | TP_SIT_FUNC_ESC | IN_BAIXA_VISAO | IN_CEGUEIRA | IN_SURDEZ | IN_DEFICIENCIA_AUDITIVA | IN_SURDO_CEGUEIRA | IN_DEFICIENCIA_FISICA | IN_DEFICIENCIA_MENTAL | IN_DEFICIT_ATENCAO | IN_DISLEXIA | IN_DISCALCULIA | IN_AUTISMO | IN_VISAO_MONOCULAR | ... | TX_RESPOSTAS_CH | TX_RESPOSTAS_LC | TX_RESPOSTAS_MT | TP_LINGUA | TX_GABARITO_CN | TX_GABARITO_CH | TX_GABARITO_LC | TX_GABARITO_MT | TP_STATUS_REDACAO | NU_NOTA_COMP1 | NU_NOTA_COMP2 | NU_NOTA_COMP3 | NU_NOTA_COMP4 | NU_NOTA_COMP5 | NU_NOTA_REDACAO | Q001 | Q002 | Q003 | Q004 | Q005 | Q006 | Q007 | Q008 | Q009 | Q010 | Q011 | Q012 | Q013 | Q014 | Q015 | Q016 | Q017 | Q018 | Q019 | Q020 | Q021 | Q022 | Q023 | Q024 | Q025 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 25 | 190001005418 | 2019 | 1501402 | Belém | 15 | PA | 32 | M | 1 | 1 | 1 | 1501402.0 | Belém | 15.0 | PA | 1 | 13 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | ACCCEEACEBCBADBEAACDBBCECCCDBCACAACACEDBACEDE | EBBAD99999BACCCDEBEBEACDDADBDECBABADBCCAAECBCC... | DDCBABCCDDBBCDBEEEBCBBEDEBCBACEDCABABEADBBCEB | 0 | DADCCEBBCCACBEEBEEBACBCDDDDADBCBBCEAEADEADAAE | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | DBEBACABCDBABECEEEDCBDCCEDCDABEDAADDDECACAECB | 1.0 | 160.0 | 200.0 | 180.0 | 200.0 | 200.0 | 940.0 | G | F | E | D | 3 | N | A | B | C | A | A | B | A | B | A | A | A | A | B | A | A | D | A | B | B |
| 321 | 190001016894 | 2019 | 1500800 | Ananindeua | 15 | PA | 17 | F | 1 | 2 | 1 | 1500800.0 | Ananindeua | 15.0 | PA | 2 | 0 | 2 | 1.0 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | ACACEEBCCBABADECAACDBBABCEEABCACACCEDEDBBAACB | EBBAE99999AACCCAEDECDADDBBEDDECEDBACBCCAAECBCA... | BEBEBBBBDCEBAECCCDBAEEDEBEEABBADACADCCACACBBA | 0 | BEEAAEBEEBADEADDADAEABCEDDDBCBCBCCACBCDADCCEB | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | BEDEEEAADBEBACABCDBABECECACADCBDCCEDCDABECDDD | 1.0 | 160.0 | 200.0 | 200.0 | 180.0 | 200.0 | 940.0 | F | G | D | D | 4 | K | A | C | D | B | A | B | B | B | A | B | A | A | B | A | A | D | B | B | B |
| 403 | 190001020313 | 2019 | 1501402 | Belém | 15 | PA | 21 | M | 1 | 1 | 1 | 1501402.0 | Belém | 15.0 | PA | 1 | 3 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | BECCEBABAEACACEEABCACEBEDDBCCDBCEECBADBCBACDB | BDABE99999BCBAAEEBBCDAAECDDCAECCACCDEDACADCBBC... | EDEADDEBAECBCDEACECEDECCCBDACEDCCABECACBBEBAA | 0 | AAECACDEADCBCDDDBCBDADAEABCEBABEEBCBEECEBDADC | BACCCBABBADCBCEEEBCACACEEDBCCADBEADBADBBBACDB | BDABEABCADBCBAADDBECDAAECDAECBECBCCDEEAAADDBBC... | EEEADBEBACABCDBABECECACDCBDCCEDCDABEDECDDDBAA | 1.0 | 160.0 | 200.0 | 200.0 | 180.0 | 180.0 | 920.0 | E | F | D | E | 3 | N | B | D | D | B | B | B | B | B | B | B | A | A | B | B | B | D | B | B | B |
| 444 | 190001021266 | 2019 | 1501402 | Belém | 15 | PA | 17 | M | 1 | 1 | 1 | 1501402.0 | Belém | 15.0 | PA | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | BAECABCCBBACBCAEEBCACBCEEDDECAEBBECBADCEAABDB | BDABE99999BCBBADDBEBDDAECBAECCDCAACDEBAAADDBEC... | AEEDCCEBBDEBDEABABCAADECCEAECCEAAAABBBEAADCEA | 0 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | BACCCBABBADCBCEEEBCACACEEDBCCADBEADBADBBBACDB | BDABEABCADBCBAADDBECDAAECDAECBECBCCDEEAAADDBBC... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 160.0 | 180.0 | 180.0 | 200.0 | 200.0 | 920.0 | F | G | E | D | 4 | I | D | E | E | B | A | B | B | B | A | B | A | B | E | A | B | E | B | D | B |
| 482 | 190001022447 | 2019 | 1500800 | Ananindeua | 15 | PA | 17 | M | 1 | 3 | 1 | 1501402.0 | Belém | 15.0 | PA | 2 | 0 | 3 | 1.0 | 0 | 15156028.0 | 1501402.0 | Belém | 15.0 | PA | 4.0 | 1.0 | 1.0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | ACACEEBCCBABADBEBACDBBABCECADCEBBDCBDDAEBAEDB | EBBAD99999BAABCDEDEDAADDDDDCDECBDDADBCDAADCECC... | AABDBBEEEBCDDBEBABABCDBABECEBACABCBCBDCCADBDA | 0 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 180.0 | 200.0 | 180.0 | 200.0 | 200.0 | 960.0 | E | D | D | D | 4 | D | A | B | D | B | A | B | A | B | A | A | A | A | B | A | A | C | B | B | B |
5 rows × 136 columns
sexo = alunos_acima['TP_SEXO']
sexo = pd.DataFrame(sexo.value_counts())
plt.style.use('seaborn')
sexo.plot.pie(y = 'TP_SEXO', figsize=(5, 5)).set_title('Distribuição dos Sexos de canditados com notas acima de 600 ENEM-2019', fontsize = 16);
sexo = alunos_acima['TP_SEXO']
sexo.value_counts(normalize = True)
M 0.512883 F 0.487117 Name: TP_SEXO, dtype: float64
Apesar da maior quantidade de candidatos do sexo feminino, percebe-se que há um leve equilíbrio de sexo entre os candidatos com notas maiores que 600, com um ganho do sexo masculino em 51,3%.
Quem tirou acima de 600 em todas as provas, é de onde?
estado_aacima = pd.DataFrame(alunos_acima['SG_UF_RESIDENCIA'].value_counts())
estado_aacima.head()
| SG_UF_RESIDENCIA | |
|---|---|
| SP | 823 |
| MG | 500 |
| RJ | 265 |
| PR | 186 |
| CE | 183 |
#Plotando o gráfico com a escala da proporção
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
ax = sns.barplot(x=estado_aacima.index, y = estado_aacima['SG_UF_RESIDENCIA'], data=estado_aacima).set_title('Distribuição de candidatos com Idade menor que 17 por Estado', fontsize = 16)
No gráfico acima, é possível visualizar que, os alunos que tiraram notas maiores que 600 em todas as provas residem, em sua maioria, no estado de São Paulo e posteriormente o estado de Minas Gerais (Os dois estados mais populosos do Brasil segundo o IBGE)
Utilizarei boxplot. Deixo um breve resumo sobre o que ele é:

Fonte: https://dev.to/giselyalves13/visualizacao-de-dados-com-seaborn-2892
sexo_ordenado = ['F', 'M']
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_MT", y = "TP_SEXO", data = dados_enem2019, order = sexo_ordenado)
plt.title("Boxplot das notas de matemática por sexo", fontsize = 16);
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_LC", y = "TP_SEXO", data = dados_enem2019, order = sexo_ordenado)
plt.title("Boxplot das notas de linguagens e códigos por sexo", fontsize = 16);
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_CN", y = "TP_SEXO", data = dados_enem2019, order = sexo_ordenado)
plt.title("Boxplot das notas de ciências da natureza por sexo", fontsize = 16);
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_CH", y = "TP_SEXO", data = dados_enem2019, order = sexo_ordenado)
plt.title("Boxplot das notas de ciências humanas por sexo", fontsize = 16);
Há um leve deslocamento das notas de quem é do sexo masculino para a direita. Essa diferença é significativa?
Análise de variância é a técnica estatística que permite avaliar afirmações sobre as médias de populações. A análise visa, fundamentalmente, verificar se existe uma diferença significativa entre as médias e se os fatores exercem influência em alguma variável dependente.
Fonte: https://pt.wikipedia.org/wiki/An%C3%A1lise_de_vari%C3%A2ncia
Para essa ocasião, estarei criando um modelo de ANOVA para realizar o teste se há diferença significativa entre os sexos. Para identificar, basta que o PR(>F) seja menor que 0,05 (nível de confiança para 95%) para contestar que há. (Hipótese Nula: Não há diferença significativa entre os grupos).
teste_sexos = dados_enem2019.dropna(subset=['NU_NOTA_MT', 'NU_NOTA_CN', 'NU_NOTA_LC', 'NU_NOTA_CH']) #eliminando os valores NaN para tornar o modelo visível e saudável.
teste_sexos.shape
(92539, 136)
modelo1 = ols('NU_NOTA_MT ~ TP_SEXO', data = teste_sexos).fit()
resultados1 = sm.stats.anova_lm(modelo1)
resultados1
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_SEXO | 1.0 | 3.980728e+07 | 3.980728e+07 | 3453.485917 | 0.0 |
| Residual | 92537.0 | 1.066646e+09 | 1.152670e+04 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de matemática. (afirmando o argumento da seção acima)
modelo2 = ols('NU_NOTA_CN ~ TP_SEXO', data = teste_sexos).fit()
resultados2 = sm.stats.anova_lm(modelo2)
resultados2
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_SEXO | 1.0 | 8.447854e+06 | 8.447854e+06 | 1476.255361 | 1.931303e-320 |
| Residual | 92537.0 | 5.295419e+08 | 5.722488e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências da natureza. (afirmando o argumento da seção acima)
modelo3 = ols('NU_NOTA_LC ~ TP_SEXO', data = teste_sexos).fit()
resultados3 = sm.stats.anova_lm(modelo3)
resultados3
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_SEXO | 1.0 | 1.401107e+05 | 140110.740867 | 35.165912 | 3.038474e-09 |
| Residual | 92537.0 | 3.686931e+08 | 3984.277235 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de linguagens e códigos. (afirmando o argumento da seção acima)
modelo4 = ols('NU_NOTA_CH ~ TP_SEXO', data = teste_sexos).fit()
resultados4 = sm.stats.anova_lm(modelo4)
resultados4
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_SEXO | 1.0 | 4.510208e+06 | 4.510208e+06 | 685.013856 | 1.923322e-150 |
| Residual | 92537.0 | 6.092740e+08 | 6.584112e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências humanas. (afirmando o argumento da seção acima)
Irei ressaltar o levantamento de movimentos sociais e linguísticos, como o Feminismo. No Brasil, após a Ditadura Militar, no início do Século 21, os movimentos sociais de inclusão ganharam cada vez mais força, principalmente no desenvolver da globalização e a criação de políticas inclusivas pelo próprio Governo Federal. Garantir acessibilidade para grupos distintos, em que HÁ SIM DESIGUALDADE, pode refletir até no desempenho educacional. A luta deve ser escutada para que esses resultados não sejam discrepantes como são.
A cor da raça declarada pelo candidado pode ser explorada pela variável TP_COR_RACA, portanto, criarei gráficos e dataframes baseados nela.
Criando um dicionário para variável
cor_raca = {
0: 'Não declarado',
1: 'Branca',
2: 'Preta',
3: 'Parda',
4: 'Amarela',
5: 'Indígena'}
Separando as colunas para análise
racas_enem2019 = dados_enem2019[['NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC', 'TP_COR_RACA', 'SG_UF_RESIDENCIA', 'TP_SEXO']]
racas_enem2019.head()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | TP_COR_RACA | SG_UF_RESIDENCIA | TP_SEXO | |
|---|---|---|---|---|---|---|---|
| 0 | 435.6 | 512.3 | 432.4 | 488.6 | 3 | PA | M |
| 1 | NaN | 409.3 | NaN | 375.3 | 3 | PA | M |
| 2 | 423.2 | 499.1 | 427.2 | 441.0 | 1 | PA | F |
| 3 | 426.2 | 578.1 | 499.9 | 551.5 | 3 | PA | F |
| 4 | 516.5 | 571.3 | 424.5 | 511.2 | 3 | PA | F |
Gerando uma coluna com as respostas
racas_enem2019['TP_COR_RACA_RESPOSTA'] = [cor_raca[i] for i in racas_enem2019.TP_COR_RACA]
racas_enem2019
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | TP_COR_RACA | SG_UF_RESIDENCIA | TP_SEXO | TP_COR_RACA_RESPOSTA | |
|---|---|---|---|---|---|---|---|---|
| 0 | 435.6 | 512.3 | 432.4 | 488.6 | 3 | PA | M | Parda |
| 1 | NaN | 409.3 | NaN | 375.3 | 3 | PA | M | Parda |
| 2 | 423.2 | 499.1 | 427.2 | 441.0 | 1 | PA | F | Branca |
| 3 | 426.2 | 578.1 | 499.9 | 551.5 | 3 | PA | F | Parda |
| 4 | 516.5 | 571.3 | 424.5 | 511.2 | 3 | PA | F | Parda |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 127375 | 502.4 | 559.6 | 539.7 | 525.7 | 1 | MG | F | Branca |
| 127376 | 449.1 | 380.9 | 418.2 | 450.3 | 2 | BA | M | Preta |
| 127377 | NaN | 516.0 | NaN | 497.9 | 3 | BA | F | Parda |
| 127378 | 564.7 | 416.2 | 455.7 | 517.3 | 2 | BA | F | Preta |
| 127379 | 466.7 | 425.5 | 438.5 | 477.1 | 2 | MG | M | Preta |
127380 rows × 8 columns
Ordenando as cores das raças em uma lista
racas_ordenadas = racas_enem2019['TP_COR_RACA_RESPOSTA'].unique()
racas_ordenadas.sort()
racas_enem_atual = pd.DataFrame(racas_enem2019['TP_COR_RACA_RESPOSTA'].value_counts())
#Plotando o gráfico com a escala da proporção
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
ax = sns.barplot(x=racas_enem_atual.index, y = racas_enem_atual['TP_COR_RACA_RESPOSTA'], data=racas_enem_atual, order = racas_ordenadas).set_title('Distribuição candidatos ENEM 2019 por Raça', fontsize = 16)
É visível que, a maioria dos candidatos são Pardos e, posteriormente, se encontra os candidatos Brancos.
De acordo com dados da Pesquisa Nacional por Amostra de Domicílios (PNAD) 2019, 42,7% dos brasileiros se declararam como brancos, 46,8% como pardos, 9,4% como pretos e 1,1% como amarelos ou indígenas. (https://educa.ibge.gov.br/jovens/conheca-o-brasil/populacao/18319-cor-ou-raca.html#:~:text=De%20acordo%20com%20dados%20da,1%25%20como%20amarelos%20ou%20ind%C3%ADgenas.)
De acordo com essa referência, é possível relacionar com a própria maioria da população brasileira os dados obtidos.
notas_maiores_racas = racas_enem2019.query('NU_NOTA_CN > 600 & NU_NOTA_CH > 600 & NU_NOTA_MT > 600 & NU_NOTA_LC > 600')
notas_maiores_racas_atual = pd.DataFrame(notas_maiores_racas['TP_COR_RACA_RESPOSTA'].value_counts(normalize = True))
notas_maiores_racas_atual
| TP_COR_RACA_RESPOSTA | |
|---|---|
| Branca | 0.637117 |
| Parda | 0.257055 |
| Preta | 0.039571 |
| Não declarado | 0.036503 |
| Amarela | 0.028834 |
| Indígena | 0.000920 |
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
ax = sns.barplot(x=notas_maiores_racas_atual.index, y = notas_maiores_racas_atual['TP_COR_RACA_RESPOSTA'], data=notas_maiores_racas_atual, order = racas_ordenadas).set_title('Distribuição das notas maiores que 600 por raça ENEM 2019', fontsize = 16)
Observe no gráfico acima que, apesar da maioria da população dos candidatos serem pardos, mais da metade das notas maiores são compostas pela cor Branca. Esse fato pode ser de acordo com o índice de que, a taxa de analfabetismo de Pretos e Pardos acima de 15 anos é mais que duas vezes maios da que dos Brancos, de acordo com o IBGE (Disponível em: https://cidades.ibge.gov.br/brasil/pesquisa/10091/82292. Acesso em: 23 out. 2020.)
Vale ressaltar que, praticamente 0% dos indígenas tiram notas maiores que 600 em todas as provas
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_MT", y = "TP_COR_RACA_RESPOSTA", data = racas_enem2019, order = racas_ordenadas)
plt.title("Boxplot das notas de matemática por cor da raça", fontsize = 16);
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_LC", y = "TP_COR_RACA_RESPOSTA", data = racas_enem2019, order = racas_ordenadas)
plt.title("Boxplot das notas de linguagens e códigos por cor da raça", fontsize = 16);
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_CN", y = "TP_COR_RACA_RESPOSTA", data = racas_enem2019, order = racas_ordenadas)
plt.title("Boxplot das notas de ciências da natureza por cor da raça", fontsize = 16);
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_CH", y = "TP_COR_RACA_RESPOSTA", data = racas_enem2019, order = racas_ordenadas)
plt.title("Boxplot das notas de ciências humanas por cor da raça", fontsize = 16);
As notas de brancos são consideravelmente maiores em relação às outras cores de raças. O efeito pode ser visto pelas medianas mais deslocadas a direita nos boxplots. Mais alguns gráficos que demonstram a desigualdade social na sociedade brasileira e a falta de democratização no acesso à uma educação de qualidade.
Análise de variância é a técnica estatística que permite avaliar afirmações sobre as médias de populações. A análise visa, fundamentalmente, verificar se existe uma diferença significativa entre as médias e se os fatores exercem influência em alguma variável dependente.
Fonte: https://pt.wikipedia.org/wiki/An%C3%A1lise_de_vari%C3%A2ncia
Para essa ocasião, estarei criando um modelo de ANOVA para realizar o teste se há diferença significativa entre as raças. Para identificar, basta que o PR(>F) seja menor que 0,05 (nível de confiança para 95%) para contestar que há. (Hipótese Nula: Não há diferença significativa entre os grupos).
teste_racas = racas_enem2019.dropna(subset=['NU_NOTA_MT', 'NU_NOTA_CN', 'NU_NOTA_LC', 'NU_NOTA_CH']) #eliminando os valores NaN para tornar o modelo visível e saudável.
modelo1 = ols('NU_NOTA_MT ~ TP_COR_RACA_RESPOSTA', data = teste_racas).fit()
resultados1 = sm.stats.anova_lm(modelo1)
resultados1
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_COR_RACA_RESPOSTA | 5.0 | 6.420354e+07 | 1.284071e+07 | 1140.023651 | 0.0 |
| Residual | 92533.0 | 1.042250e+09 | 1.126355e+04 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de matemática. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_racas['NU_NOTA_MT'], teste_racas['TP_COR_RACA_RESPOSTA'])
resultado_teste1 = mc.tukeyhsd()
resultado_teste1.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| Amarela | Branca | 34.8048 | 0.001 | 28.0959 | 41.5137 | True |
| Amarela | Indígena | -47.1337 | 0.001 | -61.5997 | -32.6677 | True |
| Amarela | Não declarado | 11.1767 | 0.0126 | 1.5157 | 20.8377 | True |
| Amarela | Parda | -17.2599 | 0.001 | -23.9314 | -10.5885 | True |
| Amarela | Preta | -27.7724 | 0.001 | -34.8724 | -20.6724 | True |
| Branca | Indígena | -81.9385 | 0.001 | -94.9608 | -68.9163 | True |
| Branca | Não declarado | -23.6282 | 0.001 | -30.9527 | -16.3036 | True |
| Branca | Parda | -52.0648 | 0.001 | -54.2609 | -49.8687 | True |
| Branca | Preta | -62.5772 | 0.001 | -65.8521 | -59.3024 | True |
| Indígena | Não declarado | 58.3103 | 0.001 | 43.5488 | 73.0719 | True |
| Indígena | Parda | 29.8737 | 0.001 | 16.8707 | 42.8768 | True |
| Indígena | Preta | 19.3613 | 0.001 | 6.1333 | 32.5893 | True |
| Não declarado | Parda | -28.4366 | 0.001 | -35.7269 | -21.1463 | True |
| Não declarado | Preta | -38.9491 | 0.001 | -46.6334 | -31.2647 | True |
| Parda | Preta | -10.5125 | 0.001 | -13.7099 | -7.315 | True |
É possível visualizar que, em todos os casos de comparação entre grupos, todos rejeitam a hipótese nula (última coluna) onde há sim diferença significativa entre os grupos.
resultado_teste1.plot_simultaneous()
Todos os grupos ocupam posições distintas, demonstrando a limitação de desempenho para cada raça (Em matemática).
modelo2 = ols('NU_NOTA_CN ~ TP_COR_RACA_RESPOSTA', data = teste_racas).fit()
resultados2 = sm.stats.anova_lm(modelo2)
resultados2
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_COR_RACA_RESPOSTA | 5.0 | 2.732724e+07 | 5.465447e+06 | 990.349249 | 0.0 |
| Residual | 92533.0 | 5.106625e+08 | 5.518707e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências da natureza. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_racas['NU_NOTA_CN'], teste_racas['TP_COR_RACA_RESPOSTA'])
resultado_teste2 = mc.tukeyhsd()
resultado_teste2.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| Amarela | Branca | 22.2236 | 0.001 | 17.5275 | 26.9196 | True |
| Amarela | Indígena | -34.1584 | 0.001 | -44.2842 | -24.0326 | True |
| Amarela | Não declarado | 10.9221 | 0.001 | 4.1597 | 17.6846 | True |
| Amarela | Parda | -12.4231 | 0.001 | -17.0929 | -7.7532 | True |
| Amarela | Preta | -16.2642 | 0.001 | -21.234 | -11.2944 | True |
| Branca | Indígena | -56.382 | 0.001 | -65.4972 | -47.2667 | True |
| Branca | Não declarado | -11.3014 | 0.001 | -16.4284 | -6.1744 | True |
| Branca | Parda | -34.6467 | 0.001 | -36.1839 | -33.1095 | True |
| Branca | Preta | -38.4878 | 0.001 | -40.7801 | -36.1955 | True |
| Indígena | Não declarado | 45.0805 | 0.001 | 34.7478 | 55.4133 | True |
| Indígena | Parda | 21.7353 | 0.001 | 12.6336 | 30.8371 | True |
| Indígena | Preta | 17.8942 | 0.001 | 8.635 | 27.1534 | True |
| Não declarado | Parda | -23.3452 | 0.001 | -28.4482 | -18.2422 | True |
| Não declarado | Preta | -27.1863 | 0.001 | -32.5652 | -21.8075 | True |
| Parda | Preta | -3.8411 | 0.001 | -6.0792 | -1.603 | True |
É possível visualizar que, em todos os casos de comparação entre grupos, todos rejeitam a hipótese nula (última coluna) onde há sim diferença significativa entre os grupos.
resultado_teste2.plot_simultaneous()
Todos os grupos ocupam posições distintas, demonstrando a limitação de desempenho para cada raça (Em ciências da natureza).
modelo3 = ols('NU_NOTA_LC ~ TP_COR_RACA_RESPOSTA', data = teste_racas).fit()
resultados3 = sm.stats.anova_lm(modelo3)
resultados3
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_COR_RACA_RESPOSTA | 5.0 | 1.852895e+07 | 3.705790e+06 | 978.885968 | 0.0 |
| Residual | 92533.0 | 3.503042e+08 | 3.785722e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de linguagens e códigos. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_racas['NU_NOTA_LC'], teste_racas['TP_COR_RACA_RESPOSTA'])
resultado_teste3 = mc.tukeyhsd()
resultado_teste3.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| Amarela | Branca | 20.9671 | 0.001 | 17.0776 | 24.8565 | True |
| Amarela | Indígena | -28.9712 | 0.001 | -37.3578 | -20.5846 | True |
| Amarela | Não declarado | 8.5728 | 0.001 | 2.9719 | 14.1737 | True |
| Amarela | Parda | -8.0099 | 0.001 | -11.8776 | -4.1421 | True |
| Amarela | Preta | -9.1309 | 0.001 | -13.2471 | -5.0147 | True |
| Branca | Indígena | -49.9383 | 0.001 | -57.4879 | -42.3887 | True |
| Branca | Não declarado | -12.3943 | 0.001 | -16.6407 | -8.1479 | True |
| Branca | Parda | -28.977 | 0.001 | -30.2501 | -27.7038 | True |
| Branca | Preta | -30.098 | 0.001 | -31.9965 | -28.1994 | True |
| Indígena | Não declarado | 37.544 | 0.001 | 28.986 | 46.1019 | True |
| Indígena | Parda | 20.9613 | 0.001 | 13.4229 | 28.4997 | True |
| Indígena | Preta | 19.8403 | 0.001 | 12.1714 | 27.5092 | True |
| Não declarado | Parda | -16.5827 | 0.001 | -20.8091 | -12.3562 | True |
| Não declarado | Preta | -17.7037 | 0.001 | -22.1586 | -13.2487 | True |
| Parda | Preta | -1.121 | 0.5136 | -2.9747 | 0.7327 | False |
Partimos agora de uma situação diferente. De fato, a maioria das cores se apresentam em uma diferença significativa, entretanto, as duas últimas da tabela não apresentaram diferença significativa. Entre pretos e pardos, não há diferença significativa. Por quê?
A minha hipótese é de que, apesar de possivelmente houver alguma diferença, o próprio IBGE em sua pesquisa de desigualdade social no Brasil considera Pretos e Pardos na mesma categoria. Essa situação pode sugerir um desempenho parecido entre as duas. (Disponível em: https://cidades.ibge.gov.br/brasil/pesquisa/10091/82292)
resultado_teste3.plot_simultaneous()
De fato, é possível observar que há uma aproximação das cores Preta e Parda nos gráficos. Já as outras, há uma disparidade exorbitante.
modelo4 = ols('NU_NOTA_CH ~ TP_COR_RACA_RESPOSTA', data = teste_racas).fit()
resultados4 = sm.stats.anova_lm(modelo4)
resultados4
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_COR_RACA_RESPOSTA | 5.0 | 2.822578e+07 | 5.645156e+06 | 892.077025 | 0.0 |
| Residual | 92533.0 | 5.855584e+08 | 6.328103e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências humanas. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_racas['NU_NOTA_CH'], teste_racas['TP_COR_RACA_RESPOSTA'])
resultado_teste4 = mc.tukeyhsd()
resultado_teste4.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| Amarela | Branca | 28.5101 | 0.001 | 23.4814 | 33.5387 | True |
| Amarela | Indígena | -27.5107 | 0.001 | -38.3536 | -16.6677 | True |
| Amarela | Não declarado | 15.966 | 0.001 | 8.7246 | 23.2074 | True |
| Amarela | Parda | -7.1511 | 0.001 | -12.1517 | -2.1505 | True |
| Amarela | Preta | -9.2301 | 0.001 | -14.5519 | -3.9083 | True |
| Branca | Indígena | -56.0207 | 0.001 | -65.7815 | -46.2599 | True |
| Branca | Não declarado | -12.5441 | 0.001 | -18.0342 | -7.054 | True |
| Branca | Parda | -35.6612 | 0.001 | -37.3073 | -34.0151 | True |
| Branca | Preta | -37.7402 | 0.001 | -40.1948 | -35.2856 | True |
| Indígena | Não declarado | 43.4767 | 0.001 | 32.4122 | 54.5412 | True |
| Indígena | Parda | 20.3596 | 0.001 | 10.6132 | 30.1059 | True |
| Indígena | Preta | 18.2806 | 0.001 | 8.3655 | 28.1956 | True |
| Não declarado | Parda | -23.1171 | 0.001 | -28.5815 | -17.6527 | True |
| Não declarado | Preta | -25.1961 | 0.001 | -30.9559 | -19.4363 | True |
| Parda | Preta | -2.079 | 0.1321 | -4.4756 | 0.3176 | False |
Observe a mesma situação de linguagens e códigos, onde há uma disparidade entre as outras raças, mas entre pardos e pretos não. De fato, é um efeito importante
resultado_teste3.plot_simultaneous()
É possível observar que há uma aproximação das cores Preta e Parda nos gráficos. Já as outras, há uma disparidade exorbitante.
Nesta seção irei realizar gráficos de mapas para analisar as médias para cada área da prova do ENEM 2019 em cada município disponível na amostra. Para isso utilizarei o dataframe já importado como nome de: coordenadas.
coordenadas.head()
| codigo_ibge | nome | latitude | longitude | capital | codigo_uf | |
|---|---|---|---|---|---|---|
| 0 | 5200050 | Abadia de Goiás | -16.75730 | -49.4412 | 0 | 52 |
| 1 | 3100104 | Abadia dos Dourados | -18.48310 | -47.3916 | 0 | 31 |
| 2 | 5200100 | Abadiânia | -16.19700 | -48.7057 | 0 | 52 |
| 3 | 3100203 | Abaeté | -19.15510 | -45.4444 | 0 | 31 |
| 4 | 1500107 | Abaetetuba | -1.72183 | -48.8788 | 0 | 15 |
Utilizarei esse dataset para concatenar os valores das coordenadas a fim de elucidar um mapa de acordo com a média das notas em cada área para cada município, conforme as seções a seguir.
dados_municipios_gerais_medias = dados_enem2019.copy()
nota_media_geral_municipio = dados_municipios_gerais_medias.groupby(['NO_MUNICIPIO_RESIDENCIA']).mean()[['NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC', 'NU_NOTA_REDACAO']]
nota_media_geral_municipio['Municipio'] = nota_media_geral_municipio.index
nota_media_geral_municipio.head()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | NU_NOTA_REDACAO | Municipio | |
|---|---|---|---|---|---|---|
| NO_MUNICIPIO_RESIDENCIA | ||||||
| Abadia de Goiás | 447.877778 | 515.766667 | 531.022222 | 501.333333 | 546.666667 | Abadia de Goiás |
| Abadia dos Dourados | 448.050000 | 461.733333 | 451.433333 | 519.216667 | 526.666667 | Abadia dos Dourados |
| Abadiânia | 446.737500 | 477.862500 | 484.612500 | 498.150000 | 580.000000 | Abadiânia |
| Abaetetuba | 450.470435 | 478.895798 | 466.254783 | 490.000000 | 566.890756 | Abaetetuba |
| Abaeté | 487.520000 | 507.940000 | 546.020000 | 533.960000 | 592.000000 | Abaeté |
concatenado_matematica = pd.merge(nota_media_geral_municipio, coordenadas, how = 'left', left_on=['Municipio'], right_on = ['nome'])
concatenado_matematica.plot.scatter(y='latitude', x = 'longitude',
c = concatenado_matematica['NU_NOTA_MT'],
cmap = 'RdYlGn',
figsize = (12,10)).set_title('Média da nota em Matemática ENEM 2019 por Município', fontsize = 16);
Pelo gráfico acima, é possível visualizar um clareamento na tonalidade das cores ao tender no Sul/Sudeste. O efeito contrátio acontece ao se direcionar para o Norte/Nordeste. Esse gráfico pode demonstrar a ainda presente desigualdade social presente no Brasil, como também um alto deficit na educação dita a disparidade de notas. É visível, também, que o Brasil de um modo geral NÃO desempenhou bem na área de Matemática.
concatenado_cn = pd.merge(nota_media_geral_municipio, coordenadas, how = 'left', left_on=['Municipio'], right_on = ['nome'])
concatenado_cn.plot.scatter(y='latitude', x = 'longitude',
c = concatenado_cn['NU_NOTA_CN'],
cmap = 'RdYlGn',
figsize = (12,10)).set_title('Média em notas de Ciências da Natureza ENEM 2019 por Município', fontsize = 16);
Novamente, o mesmo efeito ocorre com a área de Ciências da Natureza, onde há uma forte sobreposição do Sudeste e do Sul sob as outras regiões. Mais um ponto de desigualdade social. Com isso, é fato e claro onde há uma necessidade de investimento nessas áreas.
Ciências da Natureza agrega Física, Química e Biologia. Uma proposta, levantando a minha hipótese, seria levantar investimentos em laboratórios em escolas, com também propor experiências de campo para os dicentes a fim de estimular um contato maior com essa área.
concatenado_ch = pd.merge(nota_media_geral_municipio, coordenadas, how = 'left', left_on=['Municipio'], right_on = ['nome'])
concatenado_ch.plot.scatter(y='latitude', x = 'longitude',
c = concatenado_ch['NU_NOTA_CH'],
cmap = 'RdYlGn',
figsize = (12,10)).set_title('Média em notas de Ciências Humanas ENEM 2019 por Município', fontsize = 16);
Apesar dos gráficos anteriores demonstrar uma maior disparidade entre as notas das áreas, em Ciências Humanas os alunos em geral desempenharam melhor. Entretanto, é possível visualizar, ainda, um pequeno nuance na tonalidade das notas em comparação Sul/Sudeste - Norte/Nordeste.
Como já visto anteriormente, estou eliminando os valores NaN pois estou considerando-os como a não presença no dia da prova.
concatenado_lc = pd.merge(nota_media_geral_municipio, coordenadas, how = 'left', left_on=['Municipio'], right_on = ['nome'])
concatenado_lc.plot.scatter(y='latitude', x = 'longitude',
c = concatenado_lc['NU_NOTA_LC'],
cmap = 'RdYlGn',
figsize = (12,10)).set_title('Média em notas de Linguagens e CódigosENEM 2019 por Município', fontsize = 16);
A dose se repete. Novamente o Brasil de um modo geral se apresenta em um desempenho razoável, entretanto, com predominância da região ao Sul (verde mais forte.
Como já visto anteriormente, estou eliminando os valores NaN pois estou considerando-os como a não presença no dia da prova.
concatenado_red = pd.merge(nota_media_geral_municipio, coordenadas, how = 'left', left_on=['Municipio'], right_on = ['nome'])
concatenado_red.plot.scatter(y='latitude', x = 'longitude',
c = concatenado_red['NU_NOTA_REDACAO'],
cmap = 'RdYlGn',
figsize = (12,10)).set_title('Média em notas de Redação ENEM 2019 por Município', fontsize = 16);
Um pouco diferente dos gráficos anteriores, a região Sudeste foi a que mais se destacou nos gráficos. Novamente, a prevalencia das notas menores se dá no Norte e Nordeste.
A fim de analisar o estado em que resido, importarei os dados referente ao próprio estado para cada município a fim de coletar algumas informações. Os dados foram obtidos do próprio site do IBGE.
Referência: https://www.ibge.gov.br/cidades-e-estados/sp/sao-paulo.html
Importando os dados
dados_sp = pd.read_csv('https://raw.githubusercontent.com/mathllorente/idh/main/DADOS_SP_MUNICIPIOS.csv', sep = ';', encoding="ISO-8859-1")
sp_dados = dados_enem2019.loc[dados_enem2019['SG_UF_RESIDENCIA'] == 'SP'][['NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC', 'TP_COR_RACA', 'SG_UF_RESIDENCIA', 'TP_SEXO', 'NO_MUNICIPIO_RESIDENCIA']].dropna(subset=['NU_NOTA_MT', 'NU_NOTA_CN', 'NU_NOTA_LC', 'NU_NOTA_CH'])
dados_sp.head()
| Município | Código | Gentílico | Prefeito_2017 | Area_Territorial_KM2_2019 | Populacao_Estimada_Pessoas_2020 | Densidade_Demográfica_Hab_KM2_2010 | Escolarização_6_a_14_anos_%_2010 | IDHM_2010 | Mortalidade_infantil_óbitos_por_mil_nascidos_vivos_2017 | DespesasEmpenhadas_REAIS_X_1000_2017 | PIB_per_capita_REAIS_2017 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Adamantina | 3500105 | adamantinense | MÁRCIO CARDIM | 411.987 | 35111 | 82.15 | 97.6 | 0.790 | 11.63 | 13.708.366.993 | 30010.56 |
| 1 | Adolfo | 3500204 | adolfino | IZAEL ANTONIO FERNANDES | 211.055 | 3554 | 16.85 | 98.6 | 0.730 | 19.23 | 2.010.387.713 | 27634.98 |
| 2 | Aguaí | 3500303 | aguaiano | JOSÉ ALEXANDRE PEREIRA DE ARAÚJO | 474.554 | 36648 | 67.72 | 95.8 | 0.715 | 16.06 | 7.216.873.408 | 26549.19 |
| 3 | Águas da Prata | 3500402 | pratense | CARLOS HENRIQUE FORTES DEZENA | 142.673 | 8221 | 53.05 | 98.8 | 0.781 | 25.32 | 2.436.340.149 | 18974.98 |
| 4 | Águas de Lindóia | 3500501 | lindoiense | GILBERTO ABDOU HELOU | 60.126 | 18808 | 287.16 | 96.2 | 0.745 | 8.37 | 7.520.147.793 | 25554.26 |
Gerando a média por município (SP)
nota_media_sp = sp_dados.groupby(['NO_MUNICIPIO_RESIDENCIA']).mean()[['NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC']]
nota_media_sp['Municipio'] = nota_media_sp.index
nota_media_sp.head()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | Municipio | |
|---|---|---|---|---|---|
| NO_MUNICIPIO_RESIDENCIA | |||||
| Adamantina | 533.757143 | 543.085714 | 601.585714 | 534.971429 | Adamantina |
| Aguaí | 475.813333 | 528.660000 | 523.260000 | 517.433333 | Aguaí |
| Agudos | 495.500000 | 569.183333 | 590.200000 | 565.550000 | Agudos |
| Alfredo Marcondes | 488.333333 | 497.700000 | 558.700000 | 551.533333 | Alfredo Marcondes |
| Altair | 380.000000 | 492.900000 | 649.500000 | 560.200000 | Altair |
Plotando os gráficos de dispersão
concatenado_sp = pd.merge(nota_media_sp, dados_sp, how = 'left', left_on=['Municipio'], right_on = ['Município'])
idh_medias_sp = concatenado_sp[['Municipio', 'NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC', 'IDHM_2010']]
plt.figure(figsize=(15,8))
plt.subplot(2,2,1)
plt.title('Relação entre IDH do município e a média em Ciências da Natureza')
plt.scatter(data = idh_medias_sp, y = 'NU_NOTA_CN', x = 'IDHM_2010');
plt.subplot(2,2,2)
plt.title('Relação entre IDH do município e a média em Ciências Humanas')
plt.scatter(data = idh_medias_sp, y = 'NU_NOTA_CH', x = 'IDHM_2010');
plt.subplot(2,2,3)
plt.title('Relação entre IDH do município e a média em Matemática')
plt.scatter(data = idh_medias_sp, y = 'NU_NOTA_MT', x = 'IDHM_2010');
plt.subplot(2,2,4)
plt.title('Relação entre IDH do município e a média em Linguagens e Códigos')
plt.scatter(data = idh_medias_sp, y = 'NU_NOTA_LC', x = 'IDHM_2010');
Visualmente os dados se dispersam muito em relação ao IDH do município.
correlacao_sp = idh_medias_sp[['NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC', 'IDHM_2010']].corr()
sns.heatmap(correlacao_sp, cmap="Blues", center=0, annot=True);
Os valores acima são interpretados pela seguinte proposta:

De fato, há uma fraca relação entre o IDH e as provas. As que mais se destacaram pela relação foi a de Ciências da Natureza e de Ciências Humanas. Apesar de haver uma correlação fraca (não se é esperada uma correlação forte, dito que é apenas um evento de muitos) o IDH tem sim sua influência nas notas do ENEM.
Esse fator é visível a partir dos gráficos, onde há uma mínima inclinação positiva da esquerda para direita, em que quanto maior o IDH maior serão as notas.
Nesta ocasião, estarei analisando a relação entre a escolaridade dos pais dos candidados e seu desempenho nas provas. Para isso, utilizarei as variáveis Q001 e Q002
Q001 Até que série seu pai, ou o homem responsável por você, estudou?
Q002 Até que série sua mãe, ou a mulher responsável por você, estudou?
Criando um dicionário com as respostas para as questões e criando uma coluna para elucidar a resposta
respostas_escolaridade_pais = {
'A': 'Nunca estudou.',
'B': 'Não completou a 4ª série/5º ano do Ensino Fundamental.',
'C': 'Completou a 4ª série/5º ano, mas não completou a 8ª série/9º ano do Ensino Fundamental.',
'D': 'Completou a 8ª série/9º ano do Ensino Fundamental, mas não completou o Ensino Médio.',
'E': 'Completou o Ensino Médio, mas não completou a Faculdade.',
'F': 'Completou a Faculdade, mas não completou a Pós-graduação.',
'G': 'Completou a Pós-graduação.',
'H': 'Não sei.'
}
influencia_pais = dados_enem2019[['NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC', 'Q001', 'Q002', 'SG_UF_RESIDENCIA', 'NO_MUNICIPIO_RESIDENCIA']]
influencia_pais['Q001_RESPOSTA_PAI'] = [respostas_escolaridade_pais[respostas] for respostas in influencia_pais.Q001]
influencia_pais['Q002_RESPOSTA_MAE'] = [respostas_escolaridade_pais[respostas] for respostas in influencia_pais.Q002]
influencia_pais
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | Q001 | Q002 | SG_UF_RESIDENCIA | NO_MUNICIPIO_RESIDENCIA | Q001_RESPOSTA_PAI | Q002_RESPOSTA_MAE | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 435.6 | 512.3 | 432.4 | 488.6 | B | B | PA | Redenção | Não completou a 4ª série/5º ano do Ensino Fund... | Não completou a 4ª série/5º ano do Ensino Fund... |
| 1 | NaN | 409.3 | NaN | 375.3 | C | C | PA | Marabá | Completou a 4ª série/5º ano, mas não completou... | Completou a 4ª série/5º ano, mas não completou... |
| 2 | 423.2 | 499.1 | 427.2 | 441.0 | C | A | PA | Belém | Completou a 4ª série/5º ano, mas não completou... | Nunca estudou. |
| 3 | 426.2 | 578.1 | 499.9 | 551.5 | E | C | PA | São Félix do Xingu | Completou o Ensino Médio, mas não completou a ... | Completou a 4ª série/5º ano, mas não completou... |
| 4 | 516.5 | 571.3 | 424.5 | 511.2 | E | E | PA | Ananindeua | Completou o Ensino Médio, mas não completou a ... | Completou o Ensino Médio, mas não completou a ... |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 127375 | 502.4 | 559.6 | 539.7 | 525.7 | D | F | MG | Montalvânia | Completou a 8ª série/9º ano do Ensino Fundamen... | Completou a Faculdade, mas não completou a Pós... |
| 127376 | 449.1 | 380.9 | 418.2 | 450.3 | E | C | BA | Barra da Estiva | Completou o Ensino Médio, mas não completou a ... | Completou a 4ª série/5º ano, mas não completou... |
| 127377 | NaN | 516.0 | NaN | 497.9 | H | E | BA | Salvador | Não sei. | Completou o Ensino Médio, mas não completou a ... |
| 127378 | 564.7 | 416.2 | 455.7 | 517.3 | E | E | BA | Simões Filho | Completou o Ensino Médio, mas não completou a ... | Completou o Ensino Médio, mas não completou a ... |
| 127379 | 466.7 | 425.5 | 438.5 | 477.1 | E | E | MG | Belo Horizonte | Completou o Ensino Médio, mas não completou a ... | Completou o Ensino Médio, mas não completou a ... |
127380 rows × 10 columns
Analisando a distribuição das respostas referente ao Pai
pai = pd.DataFrame(influencia_pais.Q001_RESPOSTA_PAI.value_counts())
pai
| Q001_RESPOSTA_PAI | |
|---|---|
| Completou o Ensino Médio, mas não completou a Faculdade. | 32958 |
| Não completou a 4ª série/5º ano do Ensino Fundamental. | 28390 |
| Completou a 4ª série/5º ano, mas não completou a 8ª série/9º ano do Ensino Fundamental. | 17791 |
| Completou a 8ª série/9º ano do Ensino Fundamental, mas não completou o Ensino Médio. | 14771 |
| Não sei. | 11002 |
| Completou a Faculdade, mas não completou a Pós-graduação. | 9417 |
| Nunca estudou. | 7309 |
| Completou a Pós-graduação. | 5742 |
pai.plot.barh().set_title('Escolaridade dos Pais dos candidatos ENEM 2019', fontsize = 16);
Analisando a distribuição das respostas referente à Mãe
mae = pd.DataFrame(influencia_pais.Q002_RESPOSTA_MAE.value_counts())
mae
| Q002_RESPOSTA_MAE | |
|---|---|
| Completou o Ensino Médio, mas não completou a Faculdade. | 40808 |
| Não completou a 4ª série/5º ano do Ensino Fundamental. | 21378 |
| Completou a 4ª série/5º ano, mas não completou a 8ª série/9º ano do Ensino Fundamental. | 17121 |
| Completou a 8ª série/9º ano do Ensino Fundamental, mas não completou o Ensino Médio. | 16729 |
| Completou a Faculdade, mas não completou a Pós-graduação. | 12801 |
| Completou a Pós-graduação. | 10042 |
| Nunca estudou. | 4835 |
| Não sei. | 3666 |
mae.plot.barh().set_title('Escolaridade das Mães dos candidatos ENEM 2019', fontsize = 16);
É possível visualizar, nas tabelas acima, que a questão respondida por "Não Sei." no caso do pai é de 11002 e no caso da mãe é de 3666. Levanto a hipótese de uma possível evasão dos pais nas famílias, sendo mais presente a mãe.
pai['Q001_RESPOSTA_PAI'].loc[pai.index == 'Completou a Pós-graduação.'][0]/mae.sum()*100 #Proporção para pais com pós-graduação
Q002_RESPOSTA_MAE 4.507772 dtype: float64
mae['Q002_RESPOSTA_MAE'].loc[mae.index == 'Completou a Pós-graduação.'][0]/mae.sum()*100 #Proporção para mães com pós-graduação
Q002_RESPOSTA_MAE 7.883498 dtype: float64
Como é a distribuição de escolaridade a nível de Pós-graduação do pai e da mãe pelo país?
pai_com_pos = influencia_pais.loc[influencia_pais['Q001_RESPOSTA_PAI'] == 'Completou a Pós-graduação.']
estado_pai_com_pos = pai_com_pos['SG_UF_RESIDENCIA'].value_counts()
municipios_pai = estado_pai_com_pos.index
estado_pai_com_pos = pd.DataFrame(estado_pai_com_pos)
estado_pai_com_pos['Estado'] = municipios_pai
estado_pai_com_pos.head()
| SG_UF_RESIDENCIA | Estado | |
|---|---|---|
| SP | 1310 | SP |
| MG | 615 | MG |
| RJ | 502 | RJ |
| PR | 376 | PR |
| BA | 267 | BA |
estado_pai_com_pos.plot.barh(figsize=(10, 8)).set_title('Distribuição dos pais dos candidatos ENEM2019 que tem Pós-graduação por Estado', fontsize = 16);
mae_com_pos = influencia_pais.loc[influencia_pais['Q002_RESPOSTA_MAE'] == 'Completou a Pós-graduação.']
estado_mae_com_pos = mae_com_pos['SG_UF_RESIDENCIA'].value_counts()
municipios_mae = estado_mae_com_pos.index
estado_mae_com_pos = pd.DataFrame(estado_mae_com_pos)
estado_mae_com_pos['Estado'] = municipios_mae
estado_mae_com_pos.head()
| SG_UF_RESIDENCIA | Estado | |
|---|---|---|
| SP | 1772 | SP |
| MG | 1185 | MG |
| PR | 670 | PR |
| RJ | 653 | RJ |
| BA | 597 | BA |
estado_mae_com_pos.plot.barh(figsize=(10, 8)).set_title('Distribuição das mães dos candidatos ENEM2019 que tem Pós-graduação por Estado', fontsize = 16);
Majoritariamente o Estado de São Paulo ocupa a primeira posição, em segundo o estado de Minas Gerais. Portanto, os Estados do sudeste apresentam uma representatividade maior no páis conquanto aos pais com uma escolaridade mais desenvolvida. Esse fator pode ser histórico. É possível relacionar, tanto pela população maior, quanto pela política Café com Leite executada na República Velha, onde os Estados de Minas Gerais e São Paulo foram predominantes no período ante 1930. Diante disso, com a riqueza, é possível relacionar um possível cunho histórico, tanto de desenvolvimento econômico, quanto de incentivo educacional e social.
Como é o comportamento da escolaridade nas notas maiores?
notas_maiores_pai = influencia_pais.query('NU_NOTA_CN > 600 & NU_NOTA_CH > 600 & NU_NOTA_MT > 600 & NU_NOTA_LC > 600')
notas_maiores_pai_atual = pd.DataFrame(notas_maiores_pai['Q001_RESPOSTA_PAI'].value_counts(normalize = True))
notas_maiores_pai_atual
| Q001_RESPOSTA_PAI | |
|---|---|
| Completou o Ensino Médio, mas não completou a Faculdade. | 0.293865 |
| Completou a Faculdade, mas não completou a Pós-graduação. | 0.271166 |
| Completou a Pós-graduação. | 0.237117 |
| Completou a 8ª série/9º ano do Ensino Fundamental, mas não completou o Ensino Médio. | 0.070552 |
| Completou a 4ª série/5º ano, mas não completou a 8ª série/9º ano do Ensino Fundamental. | 0.049080 |
| Não completou a 4ª série/5º ano do Ensino Fundamental. | 0.041718 |
| Não sei. | 0.031595 |
| Nunca estudou. | 0.004908 |
notas_maiores_pai_atual.plot.barh().set_title('Escolaridade dos Pais dos candidatos com notas maiores que 600 ENEM 2019', fontsize = 16);
notas_maiores_mae = influencia_pais.query('NU_NOTA_CN > 600 & NU_NOTA_CH > 600 & NU_NOTA_MT > 600 & NU_NOTA_LC > 600')
notas_maiores_mae_atual = pd.DataFrame(notas_maiores_mae['Q002_RESPOSTA_MAE'].value_counts(normalize = True))
notas_maiores_mae_atual
| Q002_RESPOSTA_MAE | |
|---|---|
| Completou a Pós-graduação. | 0.304294 |
| Completou a Faculdade, mas não completou a Pós-graduação. | 0.295706 |
| Completou o Ensino Médio, mas não completou a Faculdade. | 0.287730 |
| Completou a 8ª série/9º ano do Ensino Fundamental, mas não completou o Ensino Médio. | 0.040491 |
| Completou a 4ª série/5º ano, mas não completou a 8ª série/9º ano do Ensino Fundamental. | 0.038957 |
| Não completou a 4ª série/5º ano do Ensino Fundamental. | 0.022086 |
| Não sei. | 0.007669 |
| Nunca estudou. | 0.003067 |
notas_maiores_mae_atual.plot.barh().set_title('Escolaridade das Mães dos candidatos com notas maiores que 600 ENEM 2019', fontsize = 16);
É nítido que, quanto mais desenvolvida a escolaridade dos pais, melhor é o desempenho de seus filhos.
HIPÓTESE:Além da maior presença da mãe nas famílias, a escolaridade da mãe quanto mais desenvolvida (tende à pós-gradruação) é, maior é a chance do filho tirar notas maiores que 600. Em contrapartida, a escolaridade do pai se encontra em proporções mais suaves quanto ao desenvolvimento. Portanto, a influência maior é com respeito à escolaridade da própria mãe.
É importante ressaltar que, apesar da influência mais significativa ser pela pós-graduação, apenas 7,9% das mães possuem pós-graduação completa.
Como é a distribuição das notas com candidatos que tem mãe com pós completa?
mae_com_pos.head()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | Q001 | Q002 | SG_UF_RESIDENCIA | NO_MUNICIPIO_RESIDENCIA | Q001_RESPOSTA_PAI | Q002_RESPOSTA_MAE | |
|---|---|---|---|---|---|---|---|---|---|---|
| 43 | NaN | NaN | NaN | NaN | E | G | PA | Altamira | Completou o Ensino Médio, mas não completou a ... | Completou a Pós-graduação. |
| 47 | 419.0 | 505.6 | 456.9 | 532.8 | B | G | PA | Goianésia do Pará | Não completou a 4ª série/5º ano do Ensino Fund... | Completou a Pós-graduação. |
| 96 | NaN | NaN | NaN | NaN | D | G | PA | Ourilândia do Norte | Completou a 8ª série/9º ano do Ensino Fundamen... | Completou a Pós-graduação. |
| 137 | 544.6 | 662.1 | 689.2 | 621.8 | G | G | PA | Belém | Completou a Pós-graduação. | Completou a Pós-graduação. |
| 166 | NaN | NaN | NaN | NaN | C | G | PA | Santarém | Completou a 4ª série/5º ano, mas não completou... | Completou a Pós-graduação. |
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
sns.histplot(data = mae_com_pos).set_title('Distribuição das notas dos candidatos que tem mãe com pós completa ENEM2019', fontsize = 16);
plt.figure(figsize=(10, 8))
mae_com_pos.boxplot().set_title('Distribuição das notas dos candidatos que tem mãe com pós completa ENEM2019', fontsize = 16);
mae_com_pos.describe()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | |
|---|---|---|---|---|
| count | 8410.000000 | 8732.000000 | 8410.000000 | 8732.000000 |
| mean | 528.609287 | 556.278653 | 600.746350 | 557.416892 |
| std | 81.596191 | 82.694554 | 122.054993 | 59.132590 |
| min | 327.900000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 468.225000 | 506.300000 | 501.200000 | 525.100000 |
| 50% | 538.300000 | 568.500000 | 606.850000 | 565.350000 |
| 75% | 587.000000 | 613.425000 | 692.200000 | 597.600000 |
| max | 782.700000 | 790.000000 | 985.000000 | 801.700000 |
Comparando com a distribuição das mães que não possuem pós
mae_sem_pos = influencia_pais.loc[influencia_pais['Q002_RESPOSTA_MAE'] != 'Completou a Pós-graduação.']
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
sns.histplot(data = mae_sem_pos).set_title('Distribuição das notas dos candidatos que tem mãe sem pós completa ou inferior ENEM2019', fontsize = 16);
plt.figure(figsize=(10, 8))
mae_sem_pos.boxplot().set_title('Distribuição das notas dos candidatos que tem mãe sem pós completa ou inferior ENEM2019', fontsize = 16);
mae_sem_pos.describe()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | |
|---|---|---|---|---|
| count | 84348.000000 | 89311.000000 | 84348.000000 | 89311.000000 |
| mean | 472.914379 | 502.583678 | 515.858787 | 516.851011 |
| std | 73.868072 | 81.438881 | 105.010601 | 63.926693 |
| min | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 415.300000 | 444.500000 | 432.100000 | 480.700000 |
| 50% | 465.100000 | 505.900000 | 494.200000 | 522.600000 |
| 75% | 525.600000 | 561.100000 | 586.100000 | 560.800000 |
| max | 797.300000 | 809.400000 | 973.400000 | 747.300000 |
Dado o exposto das tabelas e dos gráficos, é visível que, as médias dos alunos com mãe com pós completa são maiores daqueles que não tem. É importante ressaltar que, as notas deles também são mais próximas de uma distribuição normal, comparando os histogramas (analisando a simetria dos gráficos para cada área). Um ponto importante a se ressaltar é que, na área de Ciências da Natureza nenhum aluno com mãe com pós tirou zero, diferente daqueles que não tem que houve nota zero (além se assemelhar com uma distribuição de poisson).
plt.figure(figsize=(20, 10))
sns.boxplot(x= "NU_NOTA_MT", y ="Q002_RESPOSTA_MAE", data = influencia_pais)
plt.title("Boxplot das notas de matemática pelo escolaridade da mãe", fontsize = 16);
plt.figure(figsize=(20, 10))
sns.boxplot(x= "NU_NOTA_LC", y ="Q002_RESPOSTA_MAE", data = influencia_pais)
plt.title("Boxplot das notas de linguagens e códigos pelo escolaridade da mãe", fontsize = 16);
plt.figure(figsize=(20, 10))
sns.boxplot(x= "NU_NOTA_CH", y ="Q002_RESPOSTA_MAE", data = influencia_pais)
plt.title("Boxplot das notas de ciências humanas pelo escolaridade da mãe", fontsize = 16);
plt.figure(figsize=(20, 10))
sns.boxplot(x= "NU_NOTA_CN", y ="Q002_RESPOSTA_MAE", data = influencia_pais)
plt.title("Boxplot das notas de ciências da natureza pelo escolaridade da mãe", fontsize = 16);
Com os gráficos acima, é possível constatar o efeito da escolaridade das mães no desempenho de seus filhos. A distribuição das notas dos filhos de quem tem pós-completa é mais deslocada para direita (nota maior) do que as de quem Nunca Estudou (contém as menores notas).
Análise de variância é a técnica estatística que permite avaliar afirmações sobre as médias de populações. A análise visa, fundamentalmente, verificar se existe uma diferença significativa entre as médias e se os fatores exercem influência em alguma variável dependente.
Fonte: https://pt.wikipedia.org/wiki/An%C3%A1lise_de_vari%C3%A2ncia
Para essa ocasião, estarei criando um modelo de ANOVA para realizar o teste se há diferença significativa entre as escolaridades das mães. Para identificar, basta que o PR(>F) seja menor que 0,05 (nível de confiança para 95%) para contestar que há. (Hipótese Nula: Não há diferença significativa entre os grupos).
teste_escolaridade_mae = influencia_pais.dropna(subset=['NU_NOTA_MT', 'NU_NOTA_CN', 'NU_NOTA_LC', 'NU_NOTA_CH']) #eliminando os valores NaN para tornar o modelo visível e saudável.
Irei utilizar as respostas pelas alternativas, a fim de tornar a visualização das tabelas mais clara. Portanto, estou deixando aqui o que significa cada resposta:
A: 'Nunca estudou.'
B: 'Não completou a 4ª série/5º ano do Ensino Fundamental.',
C:'Completou a 4ª série/5º ano, mas não completou a 8ª série/9º ano do Ensino Fundamental.',
D: 'Completou a 8ª série/9º ano do Ensino Fundamental, mas não completou o Ensino Médio.',
E:'Completou o Ensino Médio, mas não completou a Faculdade.',
F: 'Completou a Faculdade, mas não completou a Pós-graduação.',
G:'Completou a Pós-graduação.',
H: 'Não sei.'
modelo1 = ols('NU_NOTA_MT ~ Q002_RESPOSTA_MAE', data = teste_escolaridade_mae).fit()
resultados1 = sm.stats.anova_lm(modelo1)
resultados1
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q002_RESPOSTA_MAE | 7.0 | 1.401612e+08 | 2.002302e+07 | 1917.381208 | 0.0 |
| Residual | 92531.0 | 9.662921e+08 | 1.044290e+04 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de matemática. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_escolaridade_mae['NU_NOTA_MT'], teste_escolaridade_mae['Q002'])
resultado_teste1 = mc.tukeyhsd()
resultado_teste1.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| A | B | 19.6263 | 0.001 | 13.436 | 25.8166 | True |
| A | C | 36.3651 | 0.001 | 30.0819 | 42.6484 | True |
| A | D | 43.1373 | 0.001 | 36.8627 | 49.4119 | True |
| A | E | 66.9077 | 0.001 | 61.0403 | 72.775 | True |
| A | F | 121.8729 | 0.001 | 115.5019 | 128.2439 | True |
| A | G | 139.5773 | 0.001 | 133.039 | 146.1156 | True |
| A | H | 24.4838 | 0.001 | 16.0972 | 32.8703 | True |
| B | C | 16.7388 | 0.001 | 12.8454 | 20.6323 | True |
| B | D | 23.511 | 0.001 | 19.6315 | 27.3904 | True |
| B | E | 47.2814 | 0.001 | 44.1025 | 50.4603 | True |
| B | F | 102.2466 | 0.001 | 98.2131 | 106.2801 | True |
| B | G | 119.951 | 0.001 | 115.6582 | 124.2439 | True |
| B | H | 4.8575 | 0.3711 | -1.9259 | 11.6408 | False |
| C | D | 6.7722 | 0.001 | 2.7461 | 10.7982 | True |
| C | E | 30.5426 | 0.001 | 27.1863 | 33.8988 | True |
| C | F | 85.5078 | 0.001 | 81.3331 | 89.6825 | True |
| C | G | 103.2122 | 0.001 | 98.7864 | 107.638 | True |
| C | H | -11.8814 | 0.001 | -18.7496 | -5.0131 | True |
| D | E | 23.7704 | 0.001 | 20.4304 | 27.1104 | True |
| D | F | 78.7356 | 0.001 | 74.574 | 82.8972 | True |
| D | G | 96.4401 | 0.001 | 92.0265 | 100.8536 | True |
| D | H | -18.6535 | 0.001 | -25.5138 | -11.7932 | True |
| E | F | 54.9652 | 0.001 | 51.4475 | 58.4829 | True |
| E | G | 72.6697 | 0.001 | 68.8573 | 76.482 | True |
| E | H | -42.4239 | 0.001 | -48.9138 | -35.934 | True |
| F | G | 17.7044 | 0.001 | 13.155 | 22.2539 | True |
| F | H | -97.3891 | 0.001 | -104.3377 | -90.4406 | True |
| G | H | -115.0936 | 0.001 | -122.1958 | -107.9913 | True |
É nítido que há uma diferença significativa entre todas as escolaridades. Ademais, é possível ressaltar que NÃO HÁ DIFERENÇA SIGNIFICATIVA entre as mães que Não completou a 4ª série/5º ano do Ensino Fundamental e as que os candidatos Não sabem.
modelo2 = ols('NU_NOTA_CN ~ Q002_RESPOSTA_MAE', data = teste_escolaridade_mae).fit()
resultados2 = sm.stats.anova_lm(modelo2)
resultados2
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q002_RESPOSTA_MAE | 7.0 | 5.812458e+07 | 8.303512e+06 | 1601.141968 | 0.0 |
| Residual | 92531.0 | 4.798652e+08 | 5.185993e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências da natureza. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_escolaridade_mae['NU_NOTA_CN'], teste_escolaridade_mae['Q002'])
resultado_teste2 = mc.tukeyhsd()
resultado_teste2.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| A | B | 8.8005 | 0.001 | 4.4382 | 13.1628 | True |
| A | C | 18.121 | 0.001 | 13.6932 | 22.5488 | True |
| A | D | 22.3664 | 0.001 | 17.9447 | 26.7881 | True |
| A | E | 37.6944 | 0.001 | 33.5597 | 41.8291 | True |
| A | F | 74.2059 | 0.001 | 69.7163 | 78.6955 | True |
| A | G | 86.0577 | 0.001 | 81.4502 | 90.6653 | True |
| A | H | 8.6081 | 0.001 | 2.6981 | 14.5181 | True |
| B | C | 9.3205 | 0.001 | 6.5768 | 12.0642 | True |
| B | D | 13.5659 | 0.001 | 10.832 | 16.2997 | True |
| B | E | 28.8939 | 0.001 | 26.6537 | 31.1341 | True |
| B | F | 65.4054 | 0.001 | 62.563 | 68.2478 | True |
| B | G | 77.2572 | 0.001 | 74.232 | 80.2824 | True |
| B | H | -0.1924 | 0.9 | -4.9726 | 4.5878 | False |
| C | D | 4.2454 | 0.001 | 1.4082 | 7.0826 | True |
| C | E | 19.5734 | 0.001 | 17.2083 | 21.9386 | True |
| C | F | 56.0849 | 0.001 | 53.143 | 59.0268 | True |
| C | G | 67.9368 | 0.001 | 64.8179 | 71.0556 | True |
| C | H | -9.5129 | 0.001 | -14.3529 | -4.6728 | True |
| D | E | 15.328 | 0.001 | 12.9743 | 17.6817 | True |
| D | F | 51.8395 | 0.001 | 48.9068 | 54.7722 | True |
| D | G | 63.6913 | 0.001 | 60.5811 | 66.8016 | True |
| D | H | -13.7583 | 0.001 | -18.5928 | -8.9238 | True |
| E | F | 36.5115 | 0.001 | 34.0325 | 38.9904 | True |
| E | G | 48.3633 | 0.001 | 45.6767 | 51.0499 | True |
| E | H | -29.0863 | 0.001 | -33.6597 | -24.5129 | True |
| F | G | 11.8518 | 0.001 | 8.6458 | 15.0579 | True |
| F | H | -65.5978 | 0.001 | -70.4945 | -60.7011 | True |
| G | H | -77.4496 | 0.001 | -82.4546 | -72.4446 | True |
Novamente, a dose anterior se repete. Não há diferença entre a categoria B e H.
modelo3 = ols('NU_NOTA_LC ~ Q002_RESPOSTA_MAE', data = teste_escolaridade_mae).fit()
resultados3 = sm.stats.anova_lm(modelo3)
resultados3
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q002_RESPOSTA_MAE | 7.0 | 3.736792e+07 | 5.338274e+06 | 1490.219112 | 0.0 |
| Residual | 92531.0 | 3.314653e+08 | 3.582208e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de linguagens e códigos. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_escolaridade_mae['NU_NOTA_LC'], teste_escolaridade_mae['Q002'])
resultado_teste3 = mc.tukeyhsd()
resultado_teste3.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| A | B | 14.7836 | 0.001 | 11.158 | 18.4092 | True |
| A | C | 24.4391 | 0.001 | 20.7591 | 28.1191 | True |
| A | D | 30.0676 | 0.001 | 26.3927 | 33.7426 | True |
| A | E | 43.0662 | 0.001 | 39.6298 | 46.5026 | True |
| A | F | 67.5385 | 0.001 | 63.8071 | 71.2699 | True |
| A | G | 74.3831 | 0.001 | 70.5537 | 78.2125 | True |
| A | H | 11.6055 | 0.001 | 6.6936 | 16.5173 | True |
| B | C | 9.6555 | 0.001 | 7.3752 | 11.9359 | True |
| B | D | 15.284 | 0.001 | 13.0119 | 17.5561 | True |
| B | E | 28.2826 | 0.001 | 26.4208 | 30.1444 | True |
| B | F | 52.7549 | 0.001 | 50.3925 | 55.1172 | True |
| B | G | 59.5995 | 0.001 | 57.0852 | 62.1138 | True |
| B | H | -3.1781 | 0.2293 | -7.151 | 0.7948 | False |
| C | D | 5.6285 | 0.001 | 3.2705 | 7.9865 | True |
| C | E | 18.6271 | 0.001 | 16.6614 | 20.5928 | True |
| C | F | 43.0993 | 0.001 | 40.6543 | 45.5444 | True |
| C | G | 49.944 | 0.001 | 47.3518 | 52.5361 | True |
| C | H | -12.8337 | 0.001 | -16.8563 | -8.811 | True |
| D | E | 12.9986 | 0.001 | 11.0424 | 14.9548 | True |
| D | F | 37.4709 | 0.001 | 35.0334 | 39.9083 | True |
| D | G | 44.3155 | 0.001 | 41.7305 | 46.9004 | True |
| D | H | -18.4621 | 0.001 | -22.4801 | -14.4442 | True |
| E | F | 24.4723 | 0.001 | 22.412 | 26.5325 | True |
| E | G | 31.3169 | 0.001 | 29.084 | 33.5497 | True |
| E | H | -31.4607 | 0.001 | -35.2618 | -27.6597 | True |
| F | G | 6.8446 | 0.001 | 4.18 | 9.5092 | True |
| F | H | -55.933 | 0.001 | -60.0027 | -51.8633 | True |
| G | H | -62.7776 | 0.001 | -66.9373 | -58.6179 | True |
Novamente, o efeito se repete.
modelo4 = ols('NU_NOTA_CH ~ Q002_RESPOSTA_MAE', data = teste_escolaridade_mae).fit()
resultados4 = sm.stats.anova_lm(modelo4)
resultados4
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q002_RESPOSTA_MAE | 7.0 | 5.555821e+07 | 7.936887e+06 | 1315.610713 | 0.0 |
| Residual | 92531.0 | 5.582260e+08 | 6.032853e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências humanas. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_escolaridade_mae['NU_NOTA_CH'], teste_escolaridade_mae['Q002'])
resultado_teste4 = mc.tukeyhsd()
resultado_teste4.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| A | B | 13.6088 | 0.001 | 8.9037 | 18.3138 | True |
| A | C | 22.3732 | 0.001 | 17.5975 | 27.1489 | True |
| A | D | 27.7563 | 0.001 | 22.9872 | 32.5254 | True |
| A | E | 43.2115 | 0.001 | 38.7519 | 47.671 | True |
| A | F | 76.7274 | 0.001 | 71.8851 | 81.5698 | True |
| A | G | 87.8537 | 0.001 | 82.8842 | 92.8232 | True |
| A | H | 10.2262 | 0.001 | 3.8519 | 16.6006 | True |
| B | C | 8.7644 | 0.001 | 5.8052 | 11.7237 | True |
| B | D | 14.1476 | 0.001 | 11.199 | 17.0962 | True |
| B | E | 29.6027 | 0.001 | 27.1865 | 32.0189 | True |
| B | F | 63.1187 | 0.001 | 60.0529 | 66.1844 | True |
| B | G | 74.2449 | 0.001 | 70.9821 | 77.5078 | True |
| B | H | -3.3825 | 0.4901 | -8.5383 | 1.7733 | False |
| C | D | 5.3831 | 0.001 | 2.3231 | 8.4432 | True |
| C | E | 20.8383 | 0.001 | 18.2873 | 23.3892 | True |
| C | F | 54.3542 | 0.001 | 51.1812 | 57.5273 | True |
| C | G | 65.4805 | 0.001 | 62.1166 | 68.8444 | True |
| C | H | -12.1469 | 0.001 | -17.3672 | -6.9266 | True |
| D | E | 15.4551 | 0.001 | 12.9165 | 17.9937 | True |
| D | F | 48.9711 | 0.001 | 45.808 | 52.1342 | True |
| D | G | 60.0973 | 0.001 | 56.7428 | 63.4519 | True |
| D | H | -17.5301 | 0.001 | -22.7444 | -12.3158 | True |
| E | F | 33.516 | 0.001 | 30.8423 | 36.1897 | True |
| E | G | 44.6422 | 0.001 | 41.7446 | 47.5399 | True |
| E | H | -32.9852 | 0.001 | -37.918 | -28.0525 | True |
| F | G | 11.1263 | 0.001 | 7.6684 | 14.5842 | True |
| F | H | -66.5012 | 0.001 | -71.7825 | -61.2198 | True |
| G | H | -77.6274 | 0.001 | -83.0256 | -72.2292 | True |
De fato, EM TODAS AS ÁREAS, todas as escolaridades fazem diferença entre elas, menos entre a categoria B e H.
De fato, a mãe ter uma escolaridade mais desenvolvida faz diferença, entretanto, não faz diferença se a mãe tem escolaridade que o filho não sabe ou que Não completou a 4ª série/5º ano do Ensino Fundamental.
É perceptível uma possível simetria e coerência no boxplot gerado com as notas de Ciências Humanas. Irei plotar um histograma com os mesmos dados.
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
enem_media_mae= plt.axvline(x = mae_com_pos['NU_NOTA_CH'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_mae = plt.axvline(x = mae_com_pos['NU_NOTA_CH'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_mae = plt.axvline(x = mae_com_pos['NU_NOTA_CH'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_mae, enem_mediana_mae, enem_moda_mae], ['Média', 'Mediana', 'Moda'])
sns.histplot(mae_com_pos['NU_NOTA_CH'], bins = 35).set_title('Distribuição das notas em Ciências Humanas dos candidatos com mãe que possui pós-graduação ENEM2019', fontsize = 16);
#Gerando a linha de densidade
sns.distplot(a = mae_com_pos['NU_NOTA_CH']).set_title('Distribuição das notas em Ciências Humanas dos candidatos com mãe que possui pós-graduação ENEM2019', fontsize = 16);
Instigado com o formato de sino, decidi verificar a partir de um teste de hipótese para verificar se os dados estão normalmente distribuídos.
A fim de que uma distribuição seja normal, neste teste de hipótese o p-value deve ser maior que 0,05
Eliminando os valores NaN
ch_mae_pos = mae_com_pos['NU_NOTA_CH'].dropna()
ch_mae_pos.shape
(8732,)
Gerando uma amostra aleatória, a fim de diminuir o dataset (a função shapiro se limita a 5000 instâncias)
np.random.seed(123)
amostra = np.random.choice(a = [0,1], size = len(ch_mae_pos), replace = True, p = [0.3,0.7])
amostra_ch_mae_pos = ch_mae_pos.loc[amostra == 0]
amostra_ch_mae_pos.shape
(2652,)
Utilizando a função shapiro do módulo stats do pacore scipy
stats.shapiro(amostra_ch_mae_pos)[1]
3.4214966360124106e-19
O valor p-value, por consequência, declara que os valores das notas não estão efetivamente normalmente distribuidos. Entretanto, o formato de sino, a aproximação da média para mediana nos deduz uma tendência à normalização, diferente do formato dos candidatos que a mãe não possui pós completa, onde há uma distorção maior.
Na prova do ENEM é possível escolher duas línguas para realizar na prova de Linguagens e Códigos. São elas: inglês e espanhol. Nos dados da amostra, é possível identificar a escolha através da variável TP_LÍNGUA, sendo: 0 inglês e 1 espanhol.
ingles = dados_enem2019.query('TP_LINGUA == 0')[['NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC', 'SG_UF_RESIDENCIA']]
espanhol = dados_enem2019.query('TP_LINGUA == 1')[['NU_NOTA_CN', 'NU_NOTA_CH', 'NU_NOTA_MT', 'NU_NOTA_LC', 'SG_UF_RESIDENCIA']]
Visualização a partir de gráficos
plt.figure(figsize=(20, 14))
plt.subplot(2, 2, 1)
sns.set_theme(style="whitegrid")
enem_media_ingles_lc = plt.axvline(x = ingles['NU_NOTA_LC'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_ingles_lc = plt.axvline(x = ingles['NU_NOTA_LC'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_ingles_lc = plt.axvline(x = ingles['NU_NOTA_LC'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_ingles_lc , enem_mediana_ingles_lc , enem_moda_ingles_lc], ['Média', 'Mediana', 'Moda'])
sns.histplot(ingles['NU_NOTA_LC'], bins = 35).set_title('Linguagens e Códigos com Inglês ENEM-2019', fontsize = 16);
plt.subplot(2, 2, 2)
sns.set_theme(style="whitegrid")
enem_media_ingles_ch = plt.axvline(x = ingles['NU_NOTA_CH'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_ingles_ch = plt.axvline(x = ingles['NU_NOTA_CH'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_ingles_ch = plt.axvline(x = ingles['NU_NOTA_CH'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_ingles_ch , enem_mediana_ingles_ch , enem_moda_ingles_ch], ['Média', 'Mediana', 'Moda'])
sns.histplot(ingles['NU_NOTA_CH'], bins = 35).set_title('Ciências Humanas com Inglês ENEM-2019', fontsize = 16);
plt.subplot(2, 2, 3)
sns.set_theme(style="whitegrid")
enem_media_ingles_mt = plt.axvline(x = ingles['NU_NOTA_MT'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_ingles_mt = plt.axvline(x = ingles['NU_NOTA_MT'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_ingles_mt = plt.axvline(x = ingles['NU_NOTA_MT'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_ingles_mt , enem_mediana_ingles_mt , enem_moda_ingles_mt], ['Média', 'Mediana', 'Moda'])
sns.histplot(ingles['NU_NOTA_MT'], bins = 35).set_title('Matemática com Inglês ENEM-2019', fontsize = 16);
plt.subplot(2, 2, 4)
sns.set_theme(style="whitegrid")
enem_media_ingles_cn = plt.axvline(x = ingles['NU_NOTA_CN'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_ingles_cn = plt.axvline(x = ingles['NU_NOTA_CN'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_ingles_cn = plt.axvline(x = ingles['NU_NOTA_CN'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_ingles_cn , enem_mediana_ingles_cn , enem_moda_ingles_cn], ['Média', 'Mediana', 'Moda'])
sns.histplot(ingles['NU_NOTA_CN'], bins = 35).set_title('Ciências da Natureza com Inglês ENEM-2019', fontsize = 16);
plt.tight_layout()
plt.show()
De onde são as pessoas que escolheram inglês?
estado_ingles = pd.DataFrame(ingles['SG_UF_RESIDENCIA'].value_counts())
#Plotando o gráfico com a escala da proporção
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
ax = sns.barplot(x=estado_ingles.index, y = estado_ingles['SG_UF_RESIDENCIA'], data=estado_ingles).set_title('Distribuição de candidatos que escolheram inglês por Estado', fontsize = 16)
Há uma concentração exorbitante do Sudeste.
Análise descritiva
ingles.describe()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | |
|---|---|---|---|---|
| count | 46104.000000 | 48447.000000 | 46104.000000 | 48447.000000 |
| mean | 497.740194 | 528.271697 | 552.991077 | 537.679732 |
| std | 79.823594 | 84.012277 | 117.326959 | 63.536275 |
| min | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 434.100000 | 471.200000 | 455.500000 | 502.600000 |
| 50% | 496.900000 | 536.500000 | 540.100000 | 545.500000 |
| 75% | 557.400000 | 588.200000 | 638.700000 | 581.500000 |
| max | 797.300000 | 809.400000 | 985.000000 | 801.700000 |
Visualização a partir de gráficos
plt.figure(figsize=(20, 14))
plt.subplot(2, 2, 1)
sns.set_theme(style="whitegrid")
enem_media_espanhol_lc = plt.axvline(x = espanhol['NU_NOTA_LC'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_espanhol_lc = plt.axvline(x = espanhol['NU_NOTA_LC'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_espanhol_lc = plt.axvline(x = espanhol['NU_NOTA_LC'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_espanhol_lc , enem_mediana_espanhol_lc , enem_moda_espanhol_lc], ['Média', 'Mediana', 'Moda'])
sns.histplot(espanhol['NU_NOTA_LC'], bins = 35).set_title('Linguagens e Códigos com Espanhol ENEM-2019', fontsize = 16);
plt.subplot(2, 2, 2)
sns.set_theme(style="whitegrid")
enem_media_espanhol_ch = plt.axvline(x = espanhol['NU_NOTA_CH'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_espanhol_ch = plt.axvline(x = espanhol['NU_NOTA_CH'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_espanhol_ch = plt.axvline(x = espanhol['NU_NOTA_CH'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_espanhol_ch , enem_mediana_espanhol_ch , enem_moda_espanhol_ch], ['Média', 'Mediana', 'Moda'])
sns.histplot(espanhol['NU_NOTA_CH'], bins = 35).set_title('Ciências Humanas com Espanhol ENEM-2019', fontsize = 16);
plt.subplot(2, 2, 3)
sns.set_theme(style="whitegrid")
enem_media_espanhol_mt = plt.axvline(x = espanhol['NU_NOTA_MT'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_espanhol_mt = plt.axvline(x = espanhol['NU_NOTA_MT'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_espanhol_mt = plt.axvline(x = espanhol['NU_NOTA_MT'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_espanhol_mt , enem_mediana_espanhol_mt , enem_moda_espanhol_mt], ['Média', 'Mediana', 'Moda'])
sns.histplot(espanhol['NU_NOTA_MT'], bins = 35).set_title('Matemática com Espanhol ENEM-2019', fontsize = 16);
plt.subplot(2, 2, 4)
sns.set_theme(style="whitegrid")
enem_media_espanhol_cn = plt.axvline(x = espanhol['NU_NOTA_CN'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_espanhol_cn = plt.axvline(x = espanhol['NU_NOTA_CN'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_espanhol_cn = plt.axvline(x = espanhol['NU_NOTA_CN'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_espanhol_cn , enem_mediana_espanhol_cn , enem_moda_espanhol_cn], ['Média', 'Mediana', 'Moda'])
sns.histplot(espanhol['NU_NOTA_CN'], bins = 35).set_title('Ciências da Natureza com Espanhol ENEM-2019', fontsize = 16);
plt.tight_layout()
plt.show()
De onde que são os candidatos que esolheram espanhol?
estado_espanhol = pd.DataFrame(espanhol['SG_UF_RESIDENCIA'].value_counts())
#Plotando o gráfico com a escala da proporção
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
ax = sns.barplot(x=estado_espanhol.index, y = estado_espanhol['SG_UF_RESIDENCIA'], data=estado_espanhol).set_title('Distribuição de candidatos que escolheram espanhol por Estado', fontsize = 16)
Os dados estão bem mais distribuídos por estado, tendo maior participação da região norte/nordeste em relação ao inglês.
Análise descritiva
espanhol.describe()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | |
|---|---|---|---|---|
| count | 46654.000000 | 49596.000000 | 46654.000000 | 49596.000000 |
| mean | 458.420976 | 486.944455 | 494.466352 | 503.646965 |
| std | 67.145864 | 76.623116 | 92.181696 | 61.016081 |
| min | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 407.300000 | 432.100000 | 422.600000 | 468.800000 |
| 50% | 450.400000 | 487.700000 | 474.300000 | 509.700000 |
| 75% | 503.900000 | 542.100000 | 551.000000 | 545.200000 |
| max | 769.900000 | 760.400000 | 932.500000 | 718.400000 |
IMPORTANTE: A média e a mediana de Ciências Humanas estão bem próximas.
Análise de variância é a técnica estatística que permite avaliar afirmações sobre as médias de populações. A análise visa, fundamentalmente, verificar se existe uma diferença significativa entre as médias e se os fatores exercem influência em alguma variável dependente.
Fonte: https://pt.wikipedia.org/wiki/An%C3%A1lise_de_vari%C3%A2ncia
Para essa ocasião, estarei criando um modelo de ANOVA para realizar o teste se há diferença significativa entre as línguas escolhidas. Para identificar, basta que o PR(>F) seja menor que 0,05 (nível de confiança para 95%) para contestar que há. (Hipótese Nula: Não há diferença significativa entre os grupos).
teste_linguas = dados_enem2019.dropna(subset=['NU_NOTA_MT', 'NU_NOTA_CN', 'NU_NOTA_LC', 'NU_NOTA_CH']) #eliminando os valores NaN para tornar o modelo visível e saudável.
modelo1 = ols('NU_NOTA_MT ~ TP_LINGUA', data = teste_linguas).fit()
resultados1 = sm.stats.anova_lm(modelo1)
resultados1
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_LINGUA | 1.0 | 7.935318e+07 | 7.935318e+07 | 7149.357194 | 0.0 |
| Residual | 92537.0 | 1.027100e+09 | 1.109934e+04 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de matemática. (afirmando o argumento da seção acima)
modelo2 = ols('NU_NOTA_CN ~ TP_LINGUA', data = teste_linguas).fit()
resultados2 = sm.stats.anova_lm(modelo2)
resultados2
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_LINGUA | 1.0 | 3.576855e+07 | 3.576855e+07 | 6590.551068 | 0.0 |
| Residual | 92537.0 | 5.022212e+08 | 5.427247e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências da natureza. (afirmando o argumento da seção acima)
modelo3 = ols('NU_NOTA_LC ~ TP_LINGUA', data = teste_linguas).fit()
resultados3 = sm.stats.anova_lm(modelo3)
resultados3
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_LINGUA | 1.0 | 2.721902e+07 | 2.721902e+07 | 7373.132663 | 0.0 |
| Residual | 92537.0 | 3.416142e+08 | 3.691649e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de linguagens e códigos. (afirmando o argumento da seção acima)
modelo4 = ols('NU_NOTA_CH ~ TP_LINGUA', data = teste_linguas).fit()
resultados4 = sm.stats.anova_lm(modelo4)
resultados4
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| TP_LINGUA | 1.0 | 3.998854e+07 | 3.998854e+07 | 6449.020482 | 0.0 |
| Residual | 92537.0 | 5.737956e+08 | 6.200716e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências humanas. (afirmando o argumento da seção acima)
De fato, o desempenho de quem escolheu a língua inglesa foi consideravelmente melhor e maior daqueles que escolheram espanhol. A distribuição da amostra está equivalente, com aproximadamente 46 mil para cada um. Vale ressaltar que, aqueles que escolheram a lingua ingles desempenharam de uma forma mais harmônica e normal (de acordo com os histogramas) em matemática e ciências da natureza.
Esse efeito pode ser causado pela segregação social. De acordo com o levantamento feito pela British Council, apenas 5% da população brasileira fala inglês (Diponível em: https://www.britishcouncil.org.br/sites/default/files/demandas_de_aprendizagempesquisacompleta.pdf. Acesso em: 22 out. 2020.). Há uma considerável desigualdade nesse quesito.
Interpreto que, pela semelhança léxica e sintática que o espanhol tem com o português atrai os candidatos que não tem familiaridade com o inglês para selecionar a mesma como opção. Esse ato separa, de forma clara, os candidatos de maiores dificuldades daqueles que possuem menos.
Aprender inglês exige, tanto um custo físico, quanto, pela maioria, um custo financeiro. Ter acesso á essas informações, acesso ao material é um cenário totalmente utópico para maioria dos Brasileiros. Portanto, é uma situação astronomicamente alarmante conquanto aos investimentos na língua inglesa, a fim de democratizar o acesso a mesma, com foco nas regiões norte/nordeste (dito que estão em menor aparição daqueles que escolheram inglês).
Será que todos os candidatos que foram no primeiro dia, também foram no segundo dia? Se não, qual fator impediu os mesmo?
Para identificar o primeiro e o segundo dia, basta uma pesquisa rápida. No primeiro dia caríam as provas de: Linguagens e Códigos, Ciências Humanas e Redação, sendo as demais no segundo dia. (Disponível em: https://g1.globo.com/educacao/enem/2019/noticia/2019/10/29/enem-2019-datas-e-horarios-das-provas.ghtml. Acesso em: 22 out. 2020.)
Eu, Matheus Leite Llorente, participei do ENEM 2019 e constato a afirmação acima.
evasao_primeiro_segundo = dados_enem2019.query('TP_PRESENCA_LC == 1 & TP_PRESENCA_CH == 1 & TP_PRESENCA_CN == 0 & TP_PRESENCA_MT == 0')#Basta verificar a presença nas provas
evasao_primeiro_segundo[provas].head()
| NU_NOTA_CN | NU_NOTA_CH | NU_NOTA_MT | NU_NOTA_LC | |
|---|---|---|---|---|
| 1 | NaN | 409.3 | NaN | 375.3 |
| 62 | NaN | 442.3 | NaN | 462.2 |
| 100 | NaN | 490.4 | NaN | 427.1 |
| 138 | NaN | 425.7 | NaN | 406.3 |
| 186 | NaN | 581.5 | NaN | 545.7 |
Constatanto que, os valores NaN significam que o candidato não compareceu no dia.
len(evasao_primeiro_segundo)/len(dados_enem2019)*100 #Proporção de evasão
4.280106767153399
De toda a amostra, aproximadamente 4,3% dos candidatos foram no primeiro dia e não foram no segundo dia.
plt.figure(figsize=(20, 14))
plt.subplot(2, 2, 1)
sns.set_theme(style="whitegrid")
enem_media_evasao_primeiro_segundo_lc = plt.axvline(x = evasao_primeiro_segundo['NU_NOTA_LC'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_evasao_primeiro_segundo_lc = plt.axvline(x = evasao_primeiro_segundo['NU_NOTA_LC'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_evasao_primeiro_segundo_lc = plt.axvline(x = evasao_primeiro_segundo['NU_NOTA_LC'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_evasao_primeiro_segundo_lc , enem_mediana_evasao_primeiro_segundo_lc , enem_moda_evasao_primeiro_segundo_lc], ['Média', 'Mediana', 'Moda'])
sns.histplot(evasao_primeiro_segundo['NU_NOTA_LC'], bins = 35).set_title('Linguagens e Códigos de candidatos que não foram para o segundo dia ENEM-2019', fontsize = 16);
plt.subplot(2, 2, 2)
sns.set_theme(style="whitegrid")
enem_media_evasao_primeiro_segundo_ch = plt.axvline(x = evasao_primeiro_segundo['NU_NOTA_CH'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_evasao_primeiro_segundo_ch = plt.axvline(x = evasao_primeiro_segundo['NU_NOTA_CH'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_evasao_primeiro_segundo_ch = plt.axvline(x = evasao_primeiro_segundo['NU_NOTA_CH'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_evasao_primeiro_segundo_ch , enem_mediana_evasao_primeiro_segundo_ch , enem_moda_evasao_primeiro_segundo_ch], ['Média', 'Mediana', 'Moda'])
sns.histplot(evasao_primeiro_segundo['NU_NOTA_CH'], bins = 35).set_title('Ciências Humanas de candidatos que não foram para o segundo dia ENEM-2019', fontsize = 16);
plt.subplot(2, 2, 3)
sns.set_theme(style="whitegrid")
enem_media_evasao_primeiro_segundo_RD = plt.axvline(x = evasao_primeiro_segundo['NU_NOTA_REDACAO'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_evasao_primeiro_segundo_RD = plt.axvline(x = evasao_primeiro_segundo['NU_NOTA_REDACAO'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_evasao_primeiro_segundo_RD = plt.axvline(x = evasao_primeiro_segundo['NU_NOTA_REDACAO'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_evasao_primeiro_segundo_RD, enem_mediana_evasao_primeiro_segundo_RD , enem_moda_evasao_primeiro_segundo_RD], ['Média', 'Mediana', 'Moda'])
sns.histplot(evasao_primeiro_segundo['NU_NOTA_REDACAO'], bins = 35).set_title('Redação de candidatos que não foram para o segundo dia ENEM-2019', fontsize = 16);
plt.tight_layout()
plt.show()
Análise descritiva
evasao_primeiro_segundo[['NU_NOTA_LC', 'NU_NOTA_CH', 'NU_NOTA_REDACAO']].describe()
| NU_NOTA_LC | NU_NOTA_CH | NU_NOTA_REDACAO | |
|---|---|---|---|
| count | 5452.000000 | 5452.000000 | 5452.000000 |
| mean | 489.546625 | 461.817351 | 427.663243 |
| std | 78.620668 | 94.198502 | 230.316887 |
| min | 0.000000 | 0.000000 | 0.000000 |
| 25% | 453.275000 | 409.300000 | 320.000000 |
| 50% | 500.800000 | 463.600000 | 480.000000 |
| 75% | 538.425000 | 522.725000 | 580.000000 |
| max | 747.300000 | 762.100000 | 980.000000 |
evasao_primeiro_segundo['NU_NOTA_REDACAO'].value_counts(normalize = True).head()*100
0.0 17.223037 560.0 6.859868 480.0 5.832722 600.0 5.539252 580.0 5.502568 Name: NU_NOTA_REDACAO, dtype: float64
permanencia_primeiro_segundo = dados_enem2019.query('TP_PRESENCA_LC == 1 & TP_PRESENCA_CH == 1 & TP_PRESENCA_CN == 1 & TP_PRESENCA_MT == 1')#Basta verificar a presença nas provas
plt.figure(figsize=(20, 14))
plt.subplot(2, 2, 1)
sns.set_theme(style="whitegrid")
enem_media_permanencia_primeiro_segundo_lc = plt.axvline(x = permanencia_primeiro_segundo['NU_NOTA_LC'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_permanencia_primeiro_segundo_lc = plt.axvline(x = permanencia_primeiro_segundo['NU_NOTA_LC'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_permanencia_primeiro_segundo_lc = plt.axvline(x = permanencia_primeiro_segundo['NU_NOTA_LC'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_permanencia_primeiro_segundo_lc , enem_mediana_permanencia_primeiro_segundo_lc , enem_moda_permanencia_primeiro_segundo_lc], ['Média', 'Mediana', 'Moda'])
sns.histplot(permanencia_primeiro_segundo['NU_NOTA_LC'], bins = 35).set_title('Linguagens e Códigos de candidatos que foram para o segundo dia ENEM-2019', fontsize = 16);
plt.subplot(2, 2, 2)
sns.set_theme(style="whitegrid")
enem_media_permanencia_primeiro_segundo_ch = plt.axvline(x = permanencia_primeiro_segundo['NU_NOTA_CH'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_permanencia_primeiro_segundo_ch = plt.axvline(x = permanencia_primeiro_segundo['NU_NOTA_CH'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_permanencia_primeiro_segundo_ch = plt.axvline(x = permanencia_primeiro_segundo['NU_NOTA_CH'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_permanencia_primeiro_segundo_ch , enem_mediana_permanencia_primeiro_segundo_ch , enem_moda_permanencia_primeiro_segundo_ch], ['Média', 'Mediana', 'Moda'])
sns.histplot(permanencia_primeiro_segundo['NU_NOTA_CH'], bins = 35).set_title('Ciências Humanas de candidatos que foram para o segundo dia ENEM-2019', fontsize = 16);
plt.subplot(2, 2, 3)
sns.set_theme(style="whitegrid")
enem_media_permanencia_primeiro_segundo_RD = plt.axvline(x = permanencia_primeiro_segundo['NU_NOTA_REDACAO'].mean(), c = "#05BA7F", linewidth = 4, linestyle = '--')
enem_mediana_permanencia_primeiro_segundo_RD = plt.axvline(x = permanencia_primeiro_segundo['NU_NOTA_REDACAO'].median(), c = "#A558C4", linewidth = 4, linestyle = ':')
enem_moda_permanencia_primeiro_segundo_RD = plt.axvline(x = permanencia_primeiro_segundo['NU_NOTA_REDACAO'].mode()[0], c = "#FF5733", linewidth = 4, linestyle = '-.')
plt.legend([enem_media_permanencia_primeiro_segundo_RD, enem_mediana_permanencia_primeiro_segundo_RD , enem_moda_permanencia_primeiro_segundo_RD], ['Média', 'Mediana', 'Moda'])
sns.histplot(permanencia_primeiro_segundo['NU_NOTA_REDACAO'], bins = 35).set_title('Redação de candidatos que foram para o segundo dia ENEM-2019', fontsize = 16);
plt.tight_layout()
plt.show()
Análise descritiva
permanencia_primeiro_segundo[['NU_NOTA_LC', 'NU_NOTA_CH', 'NU_NOTA_REDACAO']].describe()
| NU_NOTA_LC | NU_NOTA_CH | NU_NOTA_REDACAO | |
|---|---|---|---|
| count | 92539.000000 | 92539.000000 | 92539.000000 |
| mean | 522.298789 | 510.063370 | 580.080399 |
| std | 63.132783 | 81.441879 | 181.749009 |
| min | 0.000000 | 0.000000 | 0.000000 |
| 25% | 485.500000 | 450.800000 | 500.000000 |
| 50% | 527.600000 | 513.600000 | 580.000000 |
| 75% | 566.500000 | 569.100000 | 680.000000 |
| max | 801.700000 | 809.400000 | 1000.000000 |
permanencia_primeiro_segundo['NU_NOTA_REDACAO'].value_counts(normalize = True).head()*100
600.0 7.167789 560.0 6.987324 580.0 6.665298 620.0 5.270210 640.0 5.193486 Name: NU_NOTA_REDACAO, dtype: float64
É fato que, além das médias das notas serem consideravelmente menores, os alunos que zeraram a redação no primeiro dia foi exorbitantemente representativo. 17% dos candidatos que não foram para o segundo dia tiraram 0 na redação.
Leva-se em conta que, o terceito quartil de quem não foi para o segundo dia é de 580, enquanto de quem foi é de 680. Sendo assim, é possível levar em consideração que, a própria redação é um fator para evasão dos candidatos.
É possível analisar a variável TP_STATUS_REDACAO, que dita uma descrição das redações avaliadas.
#Criando um dicionário com as descrições
dic_redacao = {
1: 'Sem problemas',
2: 'Anulada',
3: 'Cópia Texto Motivador',
4: 'Em Branco',
6: 'Fuga ao tema',
7: 'Não atendimento ao tipo textual',
8: 'Texto insuficiente',
9: 'Parte desconectada'
}
evasao_primeiro_segundo['TP_STATUS_REDACAO_RESPOSTA'] = [dic_redacao[resposta] for resposta in evasao_primeiro_segundo.TP_STATUS_REDACAO]
evasao_primeiro_segundo[['TP_STATUS_REDACAO', 'TP_STATUS_REDACAO_RESPOSTA']].head()
| TP_STATUS_REDACAO | TP_STATUS_REDACAO_RESPOSTA | |
|---|---|---|
| 1 | 1.0 | Sem problemas |
| 62 | 1.0 | Sem problemas |
| 100 | 1.0 | Sem problemas |
| 138 | 1.0 | Sem problemas |
| 186 | 1.0 | Sem problemas |
status_redacao_evasao = pd.DataFrame(evasao_primeiro_segundo['TP_STATUS_REDACAO_RESPOSTA'].value_counts())
status_redacao_evasao.plot.barh().set_title('Status da redação de quem não foi para o Segundo dia de Prova ENEM 2019', fontsize = 16);
Aparentemente, a maioria das redações estavam sem problemas, seguido de provas em branco. De fato, a redação pode impulsionar uma possível desmotivação nos candidados, sendo que a maior parte zerou e aparentava estar sem problemas.
A localidade da prova pode ser um fator que compromota a ida dos candidatos até o local da prova. Irei analisar quantos candidatos fizeram a prova em local diferente do município (geral).
municipio_diferente = dados_enem2019.query('NO_MUNICIPIO_RESIDENCIA != NO_MUNICIPIO_PROVA')
municipio_diferente[['NO_MUNICIPIO_RESIDENCIA', 'NO_MUNICIPIO_PROVA']].head()
| NO_MUNICIPIO_RESIDENCIA | NO_MUNICIPIO_PROVA | |
|---|---|---|
| 36 | Sapucaia | Xinguara |
| 37 | Santa Luzia do Pará | Capanema |
| 38 | Ulianópolis | Dom Eliseu |
| 45 | Santa Bárbara do Pará | Belém |
| 48 | Maracanã | Igarapé-Açu |
print('{}% dos candidatos ENEM2019 fizeram a prova em um município diferente do que residia'.format(round(len(municipio_diferente)/len(dados_enem2019)*100, 2)))
16.95% dos candidatos ENEM2019 fizeram a prova em um município diferente do que residia
E os candidatos que não foram para o segundo dia? Quantos moravam em município diferente do que fez a prova?
municipio_diferente_evasao = evasao_primeiro_segundo.query('NO_MUNICIPIO_RESIDENCIA != NO_MUNICIPIO_PROVA')
municipio_diferente_evasao[['NO_MUNICIPIO_RESIDENCIA', 'NO_MUNICIPIO_PROVA']].head()
| NO_MUNICIPIO_RESIDENCIA | NO_MUNICIPIO_PROVA | |
|---|---|---|
| 301 | Belterra | Santarém |
| 736 | Ananindeua | Belém |
| 1149 | Novo Repartimento | Marabá |
| 1622 | São Domingos do Araguaia | Marabá |
| 2227 | Itapuã do Oeste | Ariquemes |
print('{}% dos candidatos que não fizeram o segundo dia no ENEM2019 fizeram a prova em um município diferente do que residia'.format(round(len(municipio_diferente_evasao)/len(evasao_primeiro_segundo)*100, 2)))
16.09% dos candidatos que não fizeram o segundo dia no ENEM2019 fizeram a prova em um município diferente do que residia
Morar em um município e realizar a prova em outro pode sim influenciar na evasão dos alunos do primeiro para o segundo dia. Dentre vários fatores, podemos análisar alguns, como o transporte particular.
Depender do transporte público, principalmente em casos de alogmeração em um local, pode ser uma situação caótica. Vamos analisar quantos candidatos, no geral, não tinham transporte particular.
Para isso, utilizarei as questões 10 e 11 das pesquisas:
Q010 Na sua residência tem carro?
Q011 Na sua residência tem motocicleta?
Criando um dicionário para as respostas
tem_carro_moto = {
'A': 'Não.',
'B': 'Sim, um.',
'C': 'Sim, dois.',
'D': 'Sim, três.',
'E': 'Sim, quatro ou mais.'
}
dados_enem2019_transporte = dados_enem2019.copy()
dados_enem2019_transporte['Q010_RESPOSTA'] = [tem_carro_moto[resposta] for resposta in dados_enem2019.Q010]
dados_enem2019_transporte['Q011_RESPOSTA'] = [tem_carro_moto[resposta] for resposta in dados_enem2019.Q011]
dados_enem2019_transporte[['Q010','Q010_RESPOSTA', 'Q011', 'Q011_RESPOSTA']]
| Q010 | Q010_RESPOSTA | Q011 | Q011_RESPOSTA | |
|---|---|---|---|---|
| 0 | A | Não. | C | Sim, dois. |
| 1 | A | Não. | A | Não. |
| 2 | A | Não. | A | Não. |
| 3 | A | Não. | A | Não. |
| 4 | B | Sim, um. | A | Não. |
| ... | ... | ... | ... | ... |
| 127375 | A | Não. | A | Não. |
| 127376 | A | Não. | B | Sim, um. |
| 127377 | A | Não. | A | Não. |
| 127378 | A | Não. | A | Não. |
| 127379 | B | Sim, um. | A | Não. |
127380 rows × 4 columns
Analisando a partir de gráficos
carros_enem_terounao = pd.DataFrame(dados_enem2019_transporte['Q010_RESPOSTA'].value_counts(normalize = True))
carros_enem_terounao.plot.barh().set_title('Proporção para candidatos que tem carro em sua residência', fontsize = 16);
motos_enem_terounao = pd.DataFrame(dados_enem2019_transporte['Q011_RESPOSTA'].value_counts(normalize = True))
motos_enem_terounao.plot.barh().set_title('Proporção para candidatos que tem moto em sua residência', fontsize = 16);
Percebe-se que, a maioria esmagadora dos candidatos do ENEM2019 NÃO possuíam algum tipo de transporte particular (Moto ou Carro).
evasao_primeiro_segundo['Q010_RESPOSTA'] = [tem_carro_moto[resposta] for resposta in evasao_primeiro_segundo.Q010]
evasao_primeiro_segundo['Q011_RESPOSTA'] = [tem_carro_moto[resposta] for resposta in evasao_primeiro_segundo.Q011]
evasao_primeiro_segundo[['Q010','Q010_RESPOSTA', 'Q011', 'Q011_RESPOSTA']]
| Q010 | Q010_RESPOSTA | Q011 | Q011_RESPOSTA | |
|---|---|---|---|---|
| 1 | A | Não. | A | Não. |
| 62 | A | Não. | A | Não. |
| 100 | A | Não. | A | Não. |
| 138 | A | Não. | B | Sim, um. |
| 186 | A | Não. | A | Não. |
| ... | ... | ... | ... | ... |
| 127161 | A | Não. | B | Sim, um. |
| 127220 | B | Sim, um. | B | Sim, um. |
| 127364 | A | Não. | B | Sim, um. |
| 127369 | B | Sim, um. | C | Sim, dois. |
| 127377 | A | Não. | A | Não. |
5452 rows × 4 columns
Analisando a partir de gráficos
carros_enem_terounao_evasao_primeiro_segundo = pd.DataFrame(evasao_primeiro_segundo['Q010_RESPOSTA'].value_counts(normalize = True))
carros_enem_terounao_evasao_primeiro_segundo.plot.barh().set_title('Proporção para candidatos que tem carro em sua residência', fontsize = 16);
motos_enem_terounao_evasao_primeiro_segundo = pd.DataFrame(evasao_primeiro_segundo['Q011_RESPOSTA'].value_counts(normalize = True))
motos_enem_terounao_evasao_primeiro_segundo.plot.barh().set_title('Proporção para candidatos que tem moto em sua residência');
Os valores aumentam consideravelmente.
tinham_carro_enem2019 = dados_enem2019_transporte.loc[dados_enem2019_transporte['Q010_RESPOSTA'] != 'Não.']
tinham_carro_enem2019.head()
| NU_INSCRICAO | NU_ANO | CO_MUNICIPIO_RESIDENCIA | NO_MUNICIPIO_RESIDENCIA | CO_UF_RESIDENCIA | SG_UF_RESIDENCIA | NU_IDADE | TP_SEXO | TP_ESTADO_CIVIL | TP_COR_RACA | TP_NACIONALIDADE | CO_MUNICIPIO_NASCIMENTO | NO_MUNICIPIO_NASCIMENTO | CO_UF_NASCIMENTO | SG_UF_NASCIMENTO | TP_ST_CONCLUSAO | TP_ANO_CONCLUIU | TP_ESCOLA | TP_ENSINO | IN_TREINEIRO | CO_ESCOLA | CO_MUNICIPIO_ESC | NO_MUNICIPIO_ESC | CO_UF_ESC | SG_UF_ESC | TP_DEPENDENCIA_ADM_ESC | TP_LOCALIZACAO_ESC | TP_SIT_FUNC_ESC | IN_BAIXA_VISAO | IN_CEGUEIRA | IN_SURDEZ | IN_DEFICIENCIA_AUDITIVA | IN_SURDO_CEGUEIRA | IN_DEFICIENCIA_FISICA | IN_DEFICIENCIA_MENTAL | IN_DEFICIT_ATENCAO | IN_DISLEXIA | IN_DISCALCULIA | IN_AUTISMO | IN_VISAO_MONOCULAR | ... | TX_RESPOSTAS_MT | TP_LINGUA | TX_GABARITO_CN | TX_GABARITO_CH | TX_GABARITO_LC | TX_GABARITO_MT | TP_STATUS_REDACAO | NU_NOTA_COMP1 | NU_NOTA_COMP2 | NU_NOTA_COMP3 | NU_NOTA_COMP4 | NU_NOTA_COMP5 | NU_NOTA_REDACAO | Q001 | Q002 | Q003 | Q004 | Q005 | Q006 | Q007 | Q008 | Q009 | Q010 | Q011 | Q012 | Q013 | Q014 | Q015 | Q016 | Q017 | Q018 | Q019 | Q020 | Q021 | Q022 | Q023 | Q024 | Q025 | Q010_RESPOSTA | Q011_RESPOSTA | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 4 | 190001004776 | 2019 | 1500800 | Ananindeua | 15 | PA | 16 | F | 1 | 3 | 1 | 1500800.0 | Ananindeua | 15.0 | PA | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | AECCBBCBBCBDEDECACBAABEDABBEDDADCEADDBEBDBBEB | 0 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 160.0 | 140.0 | 160.0 | 160.0 | 160.0 | 780.0 | E | E | B | D | 3 | E | A | B | C | B | A | B | A | A | A | A | A | A | B | A | A | D | A | A | B | Sim, um. | Não. |
| 8 | 190001004986 | 2019 | 1502400 | Castanhal | 15 | PA | 17 | F | 1 | 3 | 1 | 1502202.0 | Capanema | 15.0 | PA | 2 | 0 | 3 | 1.0 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | DBCAADCDADDDCECECBCBABEBDECEAABCAABACEBEBBAEE | 0 | DADCCEBBCCACBEEBEEBACBCDDDDADBCBBCEAEADEADAAE | CBABADBBCEEEBCBADCBEEDBBEADBBACDBBACCCCADACAC | BBEDABDACACBABAECBBCCADCEBDBBCDDEEAAADDBECDECA... | DBEBACABCDBABECEEEDCBDCCEDCDABEDAADDDECACAECB | 1.0 | 160.0 | 180.0 | 160.0 | 160.0 | 200.0 | 860.0 | B | E | D | B | 4 | G | A | D | D | B | A | B | A | B | B | B | A | A | C | B | A | E | A | A | B | Sim, um. | Não. |
| 12 | 190001005076 | 2019 | 1506138 | Redenção | 15 | PA | 15 | M | 1 | 3 | 1 | 1506138.0 | Redenção | 15.0 | PA | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | DAADCAABECBBCBDADDEEEBCCAABADBBBECAACBDBDDCBC | 0 | BEEAAEBEEBADEADDADAEABCEDDDBCBCBCCACBCDADCCEB | EEBCEEDBADBBCBABCCADCEBACDBBACCACACBEADBBADCB | ADBBEDCABAABBCBCDAAECDDDBAAAECADECDCEBDEEAECBD... | BEDEEEAADBEBACABCDBABECECACADCBDCCEDCDABECDDD | 1.0 | 120.0 | 180.0 | 120.0 | 140.0 | 160.0 | 720.0 | C | E | D | D | 4 | F | A | C | C | B | B | B | B | A | A | B | A | A | B | B | A | C | A | A | B | Sim, um. | Sim, um. |
| 28 | 190001005647 | 2019 | 1500107 | Abaetetuba | 15 | PA | 19 | M | 1 | 3 | 1 | 1500107.0 | Abaetetuba | 15.0 | PA | 1 | 1 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | AEEBDDEEDCADEDBEBEDCBDDCACEEDAEEBABACAAAACCBD | 1 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | CBABADBBCEEEBCBADCBEEDBBEADBBACDBBACCCCADACAC | BBEDABDACACBABAECBBCCADCEBDBBCDDEEAAADDBECDECA... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 160.0 | 120.0 | 120.0 | 180.0 | 100.0 | 680.0 | D | C | D | F | 4 | D | A | B | C | B | A | B | A | B | A | A | A | A | C | A | A | E | A | B | B | Sim, um. | Não. |
| 29 | 190001005649 | 2019 | 1507300 | São Félix do Xingu | 15 | PA | 30 | F | 1 | 3 | 1 | 1400100.0 | Boa Vista | 14.0 | RR | 1 | 12 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | AABCAEECBAECADCEBEABDBCCBADEDBCACECCACCBBBBCB | 1 | DADCCEBBCCACBEEBEEBACBCDDDDADBCBBCEAEADEADAAE | BACCCBABBADCBCEEEBCACACEEDBCCADBEADBADBBBACDB | BDABEABCADBCBAADDBECDAAECDAECBECBCCDEEAAADDBBC... | DBEBACABCDBABECEEEDCBDCCEDCDABEDAADDDECACAECB | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | C | B | A | A | 3 | D | A | B | D | B | C | C | A | B | A | A | A | A | B | A | A | D | A | C | B | Sim, um. | Sim, dois. |
5 rows × 138 columns
carro_presenca_ch = pd.DataFrame(tinham_carro_enem2019['TP_PRESENCA_CH'].value_counts())
carro_presenca_cn = pd.DataFrame(tinham_carro_enem2019['TP_PRESENCA_CN'].value_counts())
plt.figure(figsize=(20, 14))
plt.subplot(2, 2, 1)
sns.set_theme(style="whitegrid")
ax = sns.barplot(data=carro_presenca_ch, x=['Não Faltou' , 'Faltou', 'Eliminado'], y=carro_presenca_ch['TP_PRESENCA_CH'], hue='TP_PRESENCA_CH')
labels=['Eliminado', 'Faltou', 'Não Faltou']
h, l = ax.get_legend_handles_labels()
ax.legend(h, labels, title="Descrição")
plt.title('Presença no primeiro dia', fontsize = 16)
plt.subplot(2, 2, 2)
sns.set_theme(style="whitegrid")
ax = sns.barplot(data=carro_presenca_cn, x=['Não Faltou', 'Faltou', 'Eliminado'], y=carro_presenca_cn['TP_PRESENCA_CN'], hue='TP_PRESENCA_CN')
labels=['Eliminado', 'Faltou', 'Não Faltou']
h, l = ax.get_legend_handles_labels()
ax.legend(h, labels, title="Descrição")
plt.title('Presença no segundo dia', fontsize = 16)
plt.tight_layout()
plt.show()
print('{} candidatos que tinham carro faltaram no primeiro dia, ou seja {}% dos que tinham carro'.format(carro_presenca_ch.iloc[1,][0], round((carro_presenca_ch.iloc[1,][0]/len(tinham_carro_enem2019))*100,2)))
10286 candidatos que tinham carro faltaram no primeiro dia, ou seja 18.73% dos que tinham carro
print('{} candidatos que tinham carro faltaram no segundo dia, ou seja {}% dos que tinham carro'.format(carro_presenca_cn.iloc[1,][0], round((carro_presenca_cn.iloc[1,][0]/len(tinham_carro_enem2019))*100,2)))
12376 candidatos que tinham carro faltaram no segundo dia, ou seja 22.53% dos que tinham carro
tinham_moto_enem2019 = dados_enem2019_transporte.loc[dados_enem2019_transporte['Q011_RESPOSTA'] != 'Não.']
tinham_moto_enem2019.head()
| NU_INSCRICAO | NU_ANO | CO_MUNICIPIO_RESIDENCIA | NO_MUNICIPIO_RESIDENCIA | CO_UF_RESIDENCIA | SG_UF_RESIDENCIA | NU_IDADE | TP_SEXO | TP_ESTADO_CIVIL | TP_COR_RACA | TP_NACIONALIDADE | CO_MUNICIPIO_NASCIMENTO | NO_MUNICIPIO_NASCIMENTO | CO_UF_NASCIMENTO | SG_UF_NASCIMENTO | TP_ST_CONCLUSAO | TP_ANO_CONCLUIU | TP_ESCOLA | TP_ENSINO | IN_TREINEIRO | CO_ESCOLA | CO_MUNICIPIO_ESC | NO_MUNICIPIO_ESC | CO_UF_ESC | SG_UF_ESC | TP_DEPENDENCIA_ADM_ESC | TP_LOCALIZACAO_ESC | TP_SIT_FUNC_ESC | IN_BAIXA_VISAO | IN_CEGUEIRA | IN_SURDEZ | IN_DEFICIENCIA_AUDITIVA | IN_SURDO_CEGUEIRA | IN_DEFICIENCIA_FISICA | IN_DEFICIENCIA_MENTAL | IN_DEFICIT_ATENCAO | IN_DISLEXIA | IN_DISCALCULIA | IN_AUTISMO | IN_VISAO_MONOCULAR | ... | TX_RESPOSTAS_MT | TP_LINGUA | TX_GABARITO_CN | TX_GABARITO_CH | TX_GABARITO_LC | TX_GABARITO_MT | TP_STATUS_REDACAO | NU_NOTA_COMP1 | NU_NOTA_COMP2 | NU_NOTA_COMP3 | NU_NOTA_COMP4 | NU_NOTA_COMP5 | NU_NOTA_REDACAO | Q001 | Q002 | Q003 | Q004 | Q005 | Q006 | Q007 | Q008 | Q009 | Q010 | Q011 | Q012 | Q013 | Q014 | Q015 | Q016 | Q017 | Q018 | Q019 | Q020 | Q021 | Q022 | Q023 | Q024 | Q025 | Q010_RESPOSTA | Q011_RESPOSTA | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 190001004661 | 2019 | 1506138 | Redenção | 15 | PA | 17 | M | 1 | 3 | 1 | 1506138.0 | Redenção | 15.0 | PA | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | DEEDCAECDDEEECBCBECABEBAECBBCDAECAEBBBBBDCCDB | 1 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 60.0 | 100.0 | 80.0 | 80.0 | 100.0 | 420.0 | B | B | A | A | 4 | B | A | C | B | A | C | B | A | A | A | A | A | A | A | B | A | C | A | B | B | Não. | Sim, dois. |
| 5 | 190001004841 | 2019 | 1503606 | Itaituba | 15 | PA | 18 | F | 1 | 3 | 1 | 1503606.0 | Itaituba | 15.0 | PA | 2 | 0 | 2 | 1.0 | 0 | 15152120.0 | 1503606.0 | Itaituba | 15.0 | PA | 4.0 | 1.0 | 1.0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | EEBBACCDBAABCEDECEABCAEAEADEBBACCAADBCEBEADDB | 1 | DADCCEBBCCACBEEBEEBACBCDDDDADBCBBCEAEADEADAAE | BACCCBABBADCBCEEEBCACACEEDBCCADBEADBADBBBACDB | BDABEABCADBCBAADDBECDAAECDAECBECBCCDEEAAADDBBC... | DBEBACABCDBABECEEEDCBDCCEDCDABEDAADDDECACAECB | 1.0 | 140.0 | 200.0 | 200.0 | 200.0 | 160.0 | 900.0 | D | E | B | C | 2 | C | A | B | C | A | C | B | B | A | A | B | A | A | B | A | A | D | A | B | B | Não. | Sim, dois. |
| 12 | 190001005076 | 2019 | 1506138 | Redenção | 15 | PA | 15 | M | 1 | 3 | 1 | 1506138.0 | Redenção | 15.0 | PA | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | DAADCAABECBBCBDADDEEEBCCAABADBBBECAACBDBDDCBC | 0 | BEEAAEBEEBADEADDADAEABCEDDDBCBCBCCACBCDADCCEB | EEBCEEDBADBBCBABCCADCEBACDBBACCACACBEADBBADCB | ADBBEDCABAABBCBCDAAECDDDBAAAECADECDCEBDEEAECBD... | BEDEEEAADBEBACABCDBABECECACADCBDCCEDCDABECDDD | 1.0 | 120.0 | 180.0 | 120.0 | 140.0 | 160.0 | 720.0 | C | E | D | D | 4 | F | A | C | C | B | B | B | B | A | A | B | A | A | B | B | A | C | A | A | B | Sim, um. | Sim, um. |
| 13 | 190001005077 | 2019 | 1501402 | Belém | 15 | PA | 51 | F | 2 | 3 | 1 | 1501402.0 | Belém | 15.0 | PA | 1 | 13 | 1 | 1.0 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | AEAACACBAEDEAADEAAEDAEEBABADAACACCACCEEEEECBE | 0 | BEEAAEBEEBADEADDADAEABCEDDDBCBCBCCACBCDADCCEB | EEBCEEDBADBBCBABCCADCEBACDBBACCACACBEADBBADCB | ADBBEDCABAABBCBCDAAECDDDBAAAECADECDCEBDEEAECBD... | BEDEEEAADBEBACABCDBABECECACADCBDCCEDCDABECDDD | 1.0 | 120.0 | 120.0 | 80.0 | 100.0 | 20.0 | 440.0 | A | E | C | B | 5 | C | A | B | C | A | B | B | A | A | A | A | A | A | C | A | A | E | A | A | B | Não. | Sim, um. |
| 20 | 190001005274 | 2019 | 1504208 | Marabá | 15 | PA | 31 | M | 2 | 3 | 1 | 1504208.0 | Marabá | 15.0 | PA | 1 | 8 | 1 | 1.0 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | CDADAADDCDDCDBDDDACDDECEAEDDBCCDDEBAEDCCABCAA | 1 | AAECACDEADCBCDDDBCBDADAEABCEBABEEBCBEECEBDADC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | EEEADBEBACABCDBABECECACDCBDCCEDCDABEDECDDDBAA | 9.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | B | B | B | B | 4 | B | A | B | C | A | B | B | A | A | A | A | A | A | B | A | A | C | A | A | B | Não. | Sim, um. |
5 rows × 138 columns
moto_presenca_ch = pd.DataFrame(tinham_moto_enem2019['TP_PRESENCA_CH'].value_counts())
moto_presenca_cn = pd.DataFrame(tinham_moto_enem2019['TP_PRESENCA_CN'].value_counts())
plt.figure(figsize=(20, 14))
plt.subplot(2, 2, 1)
sns.set_theme(style="whitegrid")
ax = sns.barplot(data=moto_presenca_ch, x=['Não Faltou' , 'Faltou', 'Eliminado'], y=moto_presenca_ch['TP_PRESENCA_CH'], hue='TP_PRESENCA_CH')
labels=['Eliminado', 'Faltou', 'Não Faltou']
h, l = ax.get_legend_handles_labels()
ax.legend(h, labels, title="Descrição")
plt.title('Presença no primeiro dia', fontsize = 16)
plt.subplot(2, 2, 2)
sns.set_theme(style="whitegrid")
ax = sns.barplot(data=moto_presenca_cn, x=['Não Faltou', 'Faltou', 'Eliminado'], y=moto_presenca_cn['TP_PRESENCA_CN'], hue='TP_PRESENCA_CN')
labels=['Eliminado', 'Faltou', 'Não Faltou']
h, l = ax.get_legend_handles_labels()
ax.legend(h, labels, title="Descrição")
plt.title('Presença no segundo dia', fontsize = 16)
plt.tight_layout()
plt.show()
print('{} candidatos que tinham moto faltaram no primeiro dia, ou seja {}% dos que tinham moto'.format(moto_presenca_ch.iloc[1,][0], round((moto_presenca_ch.iloc[1,][0]/len(tinham_moto_enem2019))*100,2)))
6323 candidatos que tinham moto faltaram no primeiro dia, ou seja 22.14% dos que tinham moto
print('{} candidatos que tinham moto faltaram no segundo dia, ou seja {}% dos que tinham moto'.format(moto_presenca_cn.iloc[1,][0], round((moto_presenca_cn.iloc[1,][0]/len(tinham_moto_enem2019))*100,2)))
7465 candidatos que tinham moto faltaram no segundo dia, ou seja 26.14% dos que tinham moto
nao_tinham_carro_moto_enem2019 = dados_enem2019_transporte.loc[dados_enem2019_transporte['Q010_RESPOSTA'] == 'Não.']
nao_tinham_carro_moto_enem2019 = nao_tinham_carro_moto_enem2019.loc[nao_tinham_carro_moto_enem2019['Q011_RESPOSTA'] == 'Não.']
nao_tinham_carro_moto_enem2019.head()
| NU_INSCRICAO | NU_ANO | CO_MUNICIPIO_RESIDENCIA | NO_MUNICIPIO_RESIDENCIA | CO_UF_RESIDENCIA | SG_UF_RESIDENCIA | NU_IDADE | TP_SEXO | TP_ESTADO_CIVIL | TP_COR_RACA | TP_NACIONALIDADE | CO_MUNICIPIO_NASCIMENTO | NO_MUNICIPIO_NASCIMENTO | CO_UF_NASCIMENTO | SG_UF_NASCIMENTO | TP_ST_CONCLUSAO | TP_ANO_CONCLUIU | TP_ESCOLA | TP_ENSINO | IN_TREINEIRO | CO_ESCOLA | CO_MUNICIPIO_ESC | NO_MUNICIPIO_ESC | CO_UF_ESC | SG_UF_ESC | TP_DEPENDENCIA_ADM_ESC | TP_LOCALIZACAO_ESC | TP_SIT_FUNC_ESC | IN_BAIXA_VISAO | IN_CEGUEIRA | IN_SURDEZ | IN_DEFICIENCIA_AUDITIVA | IN_SURDO_CEGUEIRA | IN_DEFICIENCIA_FISICA | IN_DEFICIENCIA_MENTAL | IN_DEFICIT_ATENCAO | IN_DISLEXIA | IN_DISCALCULIA | IN_AUTISMO | IN_VISAO_MONOCULAR | ... | TX_RESPOSTAS_MT | TP_LINGUA | TX_GABARITO_CN | TX_GABARITO_CH | TX_GABARITO_LC | TX_GABARITO_MT | TP_STATUS_REDACAO | NU_NOTA_COMP1 | NU_NOTA_COMP2 | NU_NOTA_COMP3 | NU_NOTA_COMP4 | NU_NOTA_COMP5 | NU_NOTA_REDACAO | Q001 | Q002 | Q003 | Q004 | Q005 | Q006 | Q007 | Q008 | Q009 | Q010 | Q011 | Q012 | Q013 | Q014 | Q015 | Q016 | Q017 | Q018 | Q019 | Q020 | Q021 | Q022 | Q023 | Q024 | Q025 | Q010_RESPOSTA | Q011_RESPOSTA | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 190001004674 | 2019 | 1504208 | Marabá | 15 | PA | 23 | M | 1 | 3 | 1 | 1504208.0 | Marabá | 15.0 | PA | 1 | 3 | 1 | 1.0 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | NaN | 1 | NaN | CBABADBBCEEEBCBADCBEEDBBEADBBACDBBACCCCADACAC | BBEDABDACACBABAECBBCCADCEBDBBCDDEEAAADDBECDECA... | NaN | 1.0 | 80.0 | 100.0 | 80.0 | 80.0 | 60.0 | 400.0 | C | C | A | A | 4 | B | A | B | C | A | A | B | B | B | A | A | A | A | B | A | A | B | A | A | B | Não. | Não. |
| 2 | 190001004722 | 2019 | 1501402 | Belém | 15 | PA | 35 | F | 2 | 1 | 1 | 1501402.0 | Belém | 15.0 | PA | 1 | 12 | 1 | 1.0 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | DDBEADEBBCADCEEACABECBCEBADECADCEDAACBDABABCE | 1 | AAECACDEADCBCDDDBCBDADAEABCEBABEEBCBEECEBDADC | CBABADBBCEEEBCBADCBEEDBBEADBBACDBBACCCCADACAC | BBEDABDACACBABAECBBCCADCEBDBBCDDEEAAADDBECDECA... | EEEADBEBACABCDBABECECACDCBDCCEDCDABEDECDDDBAA | 1.0 | 100.0 | 120.0 | 120.0 | 100.0 | 120.0 | 560.0 | C | A | B | B | 5 | C | A | B | C | A | A | B | A | B | A | A | A | A | B | A | B | B | A | A | B | Não. | Não. |
| 3 | 190001004735 | 2019 | 1507300 | São Félix do Xingu | 15 | PA | 23 | F | 1 | 3 | 1 | 1505437.0 | Ourilândia do Norte | 15.0 | PA | 1 | 7 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | CBDEBBCBDEBCABCDBDEDADCCBEDBCAECEBEBDEBAEECBC | 1 | BEEAAEBEEBADEADDADAEABCEDDDBCBCBCCACBCDADCCEB | EEBCEEDBADBBCBABCCADCEBACDBBACCACACBEADBBADCB | ADBBEDCABAABBCBCDAAECDDDBAAAECADECDCEBDEEAECBD... | BEDEEEAADBEBACABCDBABECECACADCBDCCEDCDABECDDD | 1.0 | 100.0 | 120.0 | 120.0 | 120.0 | 40.0 | 500.0 | E | C | A | A | 1 | B | A | B | C | A | A | B | A | A | A | A | A | A | B | A | A | B | A | A | B | Não. | Não. |
| 6 | 190001004856 | 2019 | 1501402 | Belém | 15 | PA | 21 | F | 1 | 3 | 1 | 1508308.0 | Viseu | 15.0 | PA | 1 | 2 | 1 | NaN | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | DCCCAABCCBECCCDACBDECDCDCBBCECCBCECBCABBCCCEB | 1 | DADCCEBBCCACBEEBEEBACBCDDDDADBCBBCEAEADEADAAE | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | DBEBACABCDBABECEEEDCBDCCEDCDABEDAADDDECACAECB | 1.0 | 120.0 | 140.0 | 140.0 | 180.0 | 180.0 | 760.0 | H | H | A | A | 2 | C | A | C | D | A | A | B | B | B | A | B | A | A | C | A | A | C | B | A | B | Não. | Não. |
| 7 | 190001004904 | 2019 | 1501402 | Belém | 15 | PA | 19 | F | 1 | 1 | 1 | 1504307.0 | Maracanã | 15.0 | PA | 1 | 3 | 1 | 1.0 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | CBEACDDBADEDCCACACBADACBABBADCCCCACBEBDEDBAEC | 1 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | BACCCBABBADCBCEEEBCACACEEDBCCADBEADBADBBBACDB | BDABEABCADBCBAADDBECDAAECDAECBECBCCDEEAAADDBBC... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 160.0 | 140.0 | 120.0 | 140.0 | 120.0 | 680.0 | B | B | A | A | 3 | B | A | B | C | A | A | B | A | A | A | A | A | A | B | A | A | B | A | A | A | Não. | Não. |
5 rows × 138 columns
nao_carro_moto_presenca_ch = pd.DataFrame(nao_tinham_carro_moto_enem2019['TP_PRESENCA_CH'].value_counts())
nao_carro_moto_presenca_cn = pd.DataFrame(nao_tinham_carro_moto_enem2019['TP_PRESENCA_CN'].value_counts())
plt.figure(figsize=(20, 14))
plt.subplot(2, 2, 1)
sns.set_theme(style="whitegrid")
ax = sns.barplot(data=nao_carro_moto_presenca_ch, x=['Não Faltou' , 'Faltou', 'Eliminado'], y=nao_carro_moto_presenca_ch['TP_PRESENCA_CH'], hue='TP_PRESENCA_CH')
labels=['Eliminado', 'Faltou', 'Não Faltou']
h, l = ax.get_legend_handles_labels()
ax.legend(h, labels, title="Descrição")
plt.title('Presença no primeiro dia', fontsize = 16)
plt.subplot(2, 2, 2)
sns.set_theme(style="whitegrid")
ax = sns.barplot(data=nao_carro_moto_presenca_cn, x=['Não Faltou', 'Faltou', 'Eliminado'], y=nao_carro_moto_presenca_cn['TP_PRESENCA_CN'], hue='TP_PRESENCA_CN')
labels=['Eliminado', 'Faltou', 'Não Faltou']
h, l = ax.get_legend_handles_labels()
ax.legend(h, labels, title="Descrição")
plt.title('Presença no segundo dia', fontsize = 16)
plt.tight_layout()
plt.show()
print('{} candidatos que não tinham moto nem carro faltaram no primeiro dia, ou seja {}% dos que não tinham moto nem carro'.format(nao_carro_moto_presenca_ch.iloc[1,][0], round((nao_carro_moto_presenca_ch.iloc[1,][0]/len(nao_tinham_carro_moto_enem2019))*100,2)))
15059 candidatos que não tinham moto nem carro faltaram no primeiro dia, ou seja 26.36% dos que não tinham moto nem carro
print('{} candidatos que não tinham moto nem carro faltaram no segundo dia, ou seja {}% os que não tinham moto nem carro'.format(nao_carro_moto_presenca_cn.iloc[1,][0], round((nao_carro_moto_presenca_cn.iloc[1,][0]/len(nao_tinham_carro_moto_enem2019))*100,2)))
17716 candidatos que não tinham moto nem carro faltaram no segundo dia, ou seja 31.01% os que não tinham moto nem carro
É considerável que, a medida que o candidato não tem transporte particular, a possibilidade dele não ir algum dos dias é maior daqueles que tem ao menos algum tipo de transporte particular, seja moto, seja carro. Esse índice pode demonstrar a impossibilidade de descolcamento com o transporte público, dito que nesses eventos o trânsito e a procura são maiores pela aglomeração, não sendo possível atender totalmente a população. De fato, é necessária uma melhora no transporte público.
Para analisar essa situação, irei utilizar a variável Q025 do dataset:
Q025: Na sua residência tem acesso à Internet?
Criando um dicionário
acesso_internet = {
'A': 'Não',
'B': 'Sim'
}
dados_internet = dados_enem2019.copy()
dados_internet['Q025_RESPOSTA'] = [acesso_internet[resposta] for resposta in dados_internet.Q025]
dados_internet[['Q025', 'Q025_RESPOSTA']]
| Q025 | Q025_RESPOSTA | |
|---|---|---|
| 0 | B | Sim |
| 1 | B | Sim |
| 2 | B | Sim |
| 3 | B | Sim |
| 4 | B | Sim |
| ... | ... | ... |
| 127375 | B | Sim |
| 127376 | B | Sim |
| 127377 | B | Sim |
| 127378 | A | Não |
| 127379 | B | Sim |
127380 rows × 2 columns
Quantos candidatos do enem tinham internet?
tinham_acesso_internet = pd.DataFrame(dados_internet['Q025_RESPOSTA'].value_counts())
tinham_acesso_internet.plot.barh().set_title('O candidato tem acesso a internet? ENEM2019', fontsize = 16);
tinham_acesso_internet = pd.DataFrame(dados_internet['Q025_RESPOSTA'].value_counts(normalize =True))
tinham_acesso_internet
| Q025_RESPOSTA | |
|---|---|
| Sim | 0.775577 |
| Não | 0.224423 |
Aproximadamente 77,56% dos candidatos do ENEM2019 tinham acesso a internet.
internet_ordenada = dados_internet["Q025_RESPOSTA"].unique()
internet_ordenada.sort()
dados_internet['NU_NOTA_MT']
0 432.4
1 NaN
2 427.2
3 499.9
4 424.5
...
127375 539.7
127376 418.2
127377 NaN
127378 455.7
127379 438.5
Name: NU_NOTA_MT, Length: 127380, dtype: float64
plt.figure(figsize=(15, 20))
plt.subplot(2, 2, 1)
sns.boxplot(x="Q025_RESPOSTA", y = "NU_NOTA_MT", data = dados_internet, order = internet_ordenada)
plt.title("Boxplot das notas de matemática pelo acesso a internet");
plt.subplot(2, 2, 2)
sns.boxplot(x="Q025_RESPOSTA", y = "NU_NOTA_LC", data = dados_internet, order = internet_ordenada)
plt.title("Boxplot das notas de linguagens e códigos pelo acesso a internet");
plt.subplot(2, 2, 3)
sns.boxplot(x="Q025_RESPOSTA", y = "NU_NOTA_CN", data = dados_internet, order = internet_ordenada)
plt.title("Boxplot das notas de ciências da natureza pelo acesso a internet");
plt.subplot(2, 2, 4)
sns.boxplot(x="Q025_RESPOSTA", y = "NU_NOTA_CH", data = dados_internet, order = internet_ordenada)
plt.title("Boxplot das notas de ciências humanas pelo acesso a internet");
Análise de variância é a técnica estatística que permite avaliar afirmações sobre as médias de populações. A análise visa, fundamentalmente, verificar se existe uma diferença significativa entre as médias e se os fatores exercem influência em alguma variável dependente.
Fonte: https://pt.wikipedia.org/wiki/An%C3%A1lise_de_vari%C3%A2ncia
Para essa ocasião, estarei criando um modelo de ANOVA para realizar o teste se há diferença significativa entre quem tem internet e quem não tem em sua residência. Para identificar, basta que o PR(>F) seja menor que 0,05 (nível de confiança para 95%) para contestar que há. (Hipótese Nula: Não há diferença significativa entre os grupos).
teste_internet = dados_internet.dropna(subset=['NU_NOTA_MT', 'NU_NOTA_CN', 'NU_NOTA_LC', 'NU_NOTA_CH']) #eliminando os valores NaN para tornar o modelo visível e saudável.
modelo1 = ols('NU_NOTA_MT ~ Q025_RESPOSTA', data = teste_internet).fit()
resultados1 = sm.stats.anova_lm(modelo1)
resultados1
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q025_RESPOSTA | 1.0 | 5.749704e+07 | 5.749704e+07 | 5072.284224 | 0.0 |
| Residual | 92537.0 | 1.048956e+09 | 1.133553e+04 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de matemática. (afirmando o argumento da seção acima)
modelo2 = ols('NU_NOTA_CN ~ Q025_RESPOSTA', data = teste_internet).fit()
resultados2 = sm.stats.anova_lm(modelo2)
resultados2
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q025_RESPOSTA | 1.0 | 2.656844e+07 | 2.656844e+07 | 4807.316315 | 0.0 |
| Residual | 92537.0 | 5.114213e+08 | 5.526668e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências da natureza. (afirmando o argumento da seção acima)
modelo3 = ols('NU_NOTA_LC ~ Q025_RESPOSTA', data = teste_internet).fit()
resultados3 = sm.stats.anova_lm(modelo3)
resultados3
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q025_RESPOSTA | 1.0 | 2.262525e+07 | 2.262525e+07 | 6047.443434 | 0.0 |
| Residual | 92537.0 | 3.462079e+08 | 3.741292e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de linguagens e códigos. (afirmando o argumento da seção acima)
modelo4 = ols('NU_NOTA_CH ~ Q025_RESPOSTA', data = teste_internet).fit()
resultados4 = sm.stats.anova_lm(modelo4)
resultados4
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q025_RESPOSTA | 1.0 | 3.046259e+07 | 3.046259e+07 | 4832.526783 | 0.0 |
| Residual | 92537.0 | 5.833216e+08 | 6.303658e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências humanas. (afirmando o argumento da seção acima)
Os gráficos acima demonstram a relativa diferença entre quem tem internet em casa em quem não tem internet na residência. O cunho de informações que a internet proporciona e as oportunidades levam os alunos a se desempenharem melhor, ao passo que a prova consiste em questões sociais onde, na internet, pela globalização são dispostas com facilidade.
A renda familiar pode ditar vários comportamentos de uma família. Irei analisar qual é o comportamento das rendas e qual é a sua relação com as notas.
Realizando a média de renda por município
Para essa situação, irei considerar uma renda fixa para cada situação. Na questão 6, as respostas são, por exemplo: de R1500,00. Para isso, realizarei a média entre esses dois valores, e irei considerar a média como resposta.
rendas = {
'A': [0,0],
'B': [0, 998],
'C' : [998.01, 1497],
'D' : [1497.01, 1996],
'E' : [1996.01, 2495],
'F': [2495.01, 2994],
'G' : [2994.01, 3992],
'H' : [3992.01, 4990],
'I' : [4990.01, 5988],
'J' : [5988.01, 6896],
'K' : [6896.01, 7984],
'L' : [7984.01, 8982],
'M' : [8982.01, 9980],
'N' : [9980.01, 11976],
'O' : [11976.01, 14970],
'P' : [14970.01, 19960],
'Q' : [19960.01, 25000] #Considerei o aumento anterior
}
rendas = pd.DataFrame(rendas).T
rendas.columns = ['Min', 'Max']
rendas['Mean'] = round((rendas['Min'] + rendas['Max'])/2, 2)
rendas.head()
| Min | Max | Mean | |
|---|---|---|---|
| A | 0.00 | 0.0 | 0.00 |
| B | 0.00 | 998.0 | 499.00 |
| C | 998.01 | 1497.0 | 1247.51 |
| D | 1497.01 | 1996.0 | 1746.50 |
| E | 1996.01 | 2495.0 | 2245.50 |
renda_media = rendas['Mean'].to_dict()
renda_media
{'A': 0.0,
'B': 499.0,
'C': 1247.51,
'D': 1746.5,
'E': 2245.5,
'F': 2744.5,
'G': 3493.0,
'H': 4491.0,
'I': 5489.0,
'J': 6442.0,
'K': 7440.0,
'L': 8483.01,
'M': 9481.01,
'N': 10978.0,
'O': 13473.0,
'P': 17465.0,
'Q': 22480.0}
dados_renda = dados_enem2019.copy()
dados_renda['Q006_RESPOSTA'] = [renda_media[resposta] for resposta in dados_renda.Q006]
dados_renda[['Q006', 'Q006_RESPOSTA']].head()
| Q006 | Q006_RESPOSTA | |
|---|---|---|
| 0 | B | 499.00 |
| 1 | B | 499.00 |
| 2 | C | 1247.51 |
| 3 | B | 499.00 |
| 4 | E | 2245.50 |
renda_media_grafico = dados_renda[['NO_MUNICIPIO_RESIDENCIA', 'CO_MUNICIPIO_RESIDENCIA', 'Q006_RESPOSTA']]
media_renda_familiar = renda_media_grafico.groupby(['NO_MUNICIPIO_RESIDENCIA']).sum()['Q006_RESPOSTA']
quantidade_renda =renda_media_grafico.groupby(['NO_MUNICIPIO_RESIDENCIA']).count()
quantidade_renda['Quantidade'] = quantidade_renda['Q006_RESPOSTA']
quantidade_renda = quantidade_renda.drop(columns=['CO_MUNICIPIO_RESIDENCIA','Q006_RESPOSTA'])
media_renda = media_renda_familiar/quantidade_renda['Quantidade']
data_renda = pd.DataFrame(media_renda)
data_renda.columns = ['Mean']
municipios_renda = data_renda.index
data_renda['Municipio'] = municipios_renda
concatenado_renda = pd.merge(data_renda, coordenadas, how = 'left', left_on=['Municipio'], right_on = ['nome'])
concatenado_renda.plot.scatter(y='latitude', x = 'longitude',
c = concatenado_renda['Mean'],
cmap = 'YlGnBu',
figsize = (12,10)).set_title('Distribuição de renda familiar dos candidatos ENEM 2019 por Município', fontsize = 16);
Há uma nítida expressão de renda baixa nas regiões ao norte/nordeste do país. Reforçando os argumentos anteriores disponibilizados pelos gráficos e pelas conclusões aqui presentes, a região sul/sudeste é aquela que disponibiliza maior renda familiar, como também, de uma educação mais qualificada para o ENEM. Vamos comparar o mesmo gráfico, agora observando as médias das notas gerais do ENEM2019 para cada candidato.
media_notas_geral = dados_enem2019[['NO_MUNICIPIO_RESIDENCIA', 'CO_MUNICIPIO_RESIDENCIA', 'NU_NOTA_MT', 'NU_NOTA_CH', 'NU_NOTA_LC', 'NU_NOTA_CN', 'NU_NOTA_REDACAO']]
media_notas_geral['Média Geral'] = round((media_notas_geral['NU_NOTA_MT'] + media_notas_geral['NU_NOTA_CH'] + media_notas_geral['NU_NOTA_LC'] + media_notas_geral['NU_NOTA_CN'] + media_notas_geral['NU_NOTA_REDACAO'])/5, 2)
media_notas_geral.head()
| NO_MUNICIPIO_RESIDENCIA | CO_MUNICIPIO_RESIDENCIA | NU_NOTA_MT | NU_NOTA_CH | NU_NOTA_LC | NU_NOTA_CN | NU_NOTA_REDACAO | Média Geral | |
|---|---|---|---|---|---|---|---|---|
| 0 | Redenção | 1506138 | 432.4 | 512.3 | 488.6 | 435.6 | 420.0 | 457.78 |
| 1 | Marabá | 1504208 | NaN | 409.3 | 375.3 | NaN | 400.0 | NaN |
| 2 | Belém | 1501402 | 427.2 | 499.1 | 441.0 | 423.2 | 560.0 | 470.10 |
| 3 | São Félix do Xingu | 1507300 | 499.9 | 578.1 | 551.5 | 426.2 | 500.0 | 511.14 |
| 4 | Ananindeua | 1500800 | 424.5 | 571.3 | 511.2 | 516.5 | 780.0 | 560.70 |
Há medias contém valores faltantes, irei filtrar apenas aquelas médias que obtém uma constante fixa.
media_sem_nota_zero = media_notas_geral.loc[media_notas_geral['Média Geral'].isna() == False]
media_sem_nota_zero.head()
| NO_MUNICIPIO_RESIDENCIA | CO_MUNICIPIO_RESIDENCIA | NU_NOTA_MT | NU_NOTA_CH | NU_NOTA_LC | NU_NOTA_CN | NU_NOTA_REDACAO | Média Geral | |
|---|---|---|---|---|---|---|---|---|
| 0 | Redenção | 1506138 | 432.4 | 512.3 | 488.6 | 435.6 | 420.0 | 457.78 |
| 2 | Belém | 1501402 | 427.2 | 499.1 | 441.0 | 423.2 | 560.0 | 470.10 |
| 3 | São Félix do Xingu | 1507300 | 499.9 | 578.1 | 551.5 | 426.2 | 500.0 | 511.14 |
| 4 | Ananindeua | 1500800 | 424.5 | 571.3 | 511.2 | 516.5 | 780.0 | 560.70 |
| 5 | Itaituba | 1503606 | 615.6 | 618.7 | 607.5 | 559.6 | 900.0 | 660.28 |
Irei, agora, realizar uma média de nota para cada município
media_nota_municipio = media_sem_nota_zero.groupby(['NO_MUNICIPIO_RESIDENCIA']).sum()['Média Geral']
quantidade_notas_municpio =media_sem_nota_zero.groupby(['NO_MUNICIPIO_RESIDENCIA']).count()
quantidade_notas_municpio['Quantidade'] = quantidade_notas_municpio['Média Geral']
quantidade_notas_municpio = quantidade_notas_municpio.drop(columns=['CO_MUNICIPIO_RESIDENCIA','Média Geral'])
media_notas_por_municipio = media_nota_municipio/quantidade_renda['Quantidade']
data_nota_municipio = pd.DataFrame(media_notas_por_municipio)
data_nota_municipio.columns = ['Mean']
municipios_nota_municipio = data_nota_municipio.index
data_nota_municipio['Municipio'] = municipios_nota_municipio
data_nota_municipio.head()
| Mean | Municipio | |
|---|---|---|
| NO_MUNICIPIO_RESIDENCIA | ||
| Abadia de Goiás | 326.914286 | Abadia de Goiás |
| Abadia dos Dourados | 361.065000 | Abadia dos Dourados |
| Abadiânia | 361.798182 | Abadiânia |
| Abaetetuba | 340.454545 | Abaetetuba |
| Abaeté | 410.375385 | Abaeté |
concatenado_media_nota_municipio = pd.merge(data_nota_municipio, coordenadas, how = 'left', left_on=['Municipio'], right_on = ['nome'])
concatenado_media_nota_municipio.plot.scatter(y='latitude', x = 'longitude',
c = concatenado_media_nota_municipio['Mean'],
cmap = 'OrRd',
figsize = (12,10)).set_title('Distribuição média geral ENEM 2019 por Município', fontsize = 16);
Observando o gráfico acima, é visível que há uma aparição maior de maiores médias na região Sul e Sudeste, reafirmando a situação anterior, onde há mais renda há um melhor desempenho no Enem.
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
ax = sns.barplot(x=estado_aacima.index, y = estado_aacima['SG_UF_RESIDENCIA'], data=estado_aacima).set_title('Distribuição de candidatos com Idade menor que 17 por Estado', fontsize = 16)
Reorganizando a resposta, de forma a torná-la categórica
rendas = {
'A': 'Nenhuma renda.',
'B': 'Até R$ 998,00.',
'C' : 'De R$ 998,01 até R$ 1.497,00.',
'D' : 'De R$ 1.497,01 até R$ 1.996,00.',
'E' : 'De R$ 1.996,01 até R$ 2.495,00.',
'F': 'De R$ 2.495,01 até R$ 2.994,00.',
'G' :'De R$ 2.994,01 até R$ 3.992,00.',
'H' : 'De R$ 3.992,01 até R$ 4.990,00.',
'I' : 'De R$ 4.990,01 até R$ 5.988,00.',
'J' : 'De R$ 5.988,01 até R$ 6.986,00.',
'K' : 'De R$ 6.986,01 até R$ 7.984,00.',
'L' : 'De R$ 7.984,01 até R$ 8.982,00.',
'M' :'De R$ 8.982,01 até R$ 9.980,00.',
'N' : 'De R$ 9.980,01 até R$ 11.976,00.',
'O' : 'De R$ 11.976,01 até R$ 14.970,00.',
'P' : 'De R$ 14.970,01 até R$ 19.960,00.',
'Q' :'Mais de R$ 19.960,00.'
}
dados_renda = dados_enem2019.copy()
dados_renda['Q006_RESPOSTA'] = [rendas[resposta] for resposta in dados_renda.Q006]
dados_renda[['Q006', 'Q006_RESPOSTA']].head()
| Q006 | Q006_RESPOSTA | |
|---|---|---|
| 0 | B | Até R$ 998,00. |
| 1 | B | Até R$ 998,00. |
| 2 | C | De R 1.497,00. |
| 3 | B | Até R$ 998,00. |
| 4 | E | De R 2.495,00. |
renda_ordenada = pd.DataFrame([rendas])
renda_ordenada = list(renda_ordenada.T[0])
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_MT", y = "Q006_RESPOSTA", data = dados_renda, order = renda_ordenada)
plt.title("Boxplot das notas de matemática pela renda", fontsize = 16);
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_LC", y = "Q006_RESPOSTA", data = dados_renda, order = renda_ordenada)
plt.title("Boxplot das notas de linguagens e códigos pela renda", fontsize = 16);
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_CH", y = "Q006_RESPOSTA", data = dados_renda, order = renda_ordenada)
plt.title("Boxplot das notas de ciências humanas e códigos pela renda", fontsize = 16);
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_CN", y = "Q006_RESPOSTA", data = dados_renda, order = renda_ordenada)
plt.title("Boxplot das notas de ciências da natureza e códigos pela renda", fontsize = 16);
plt.figure(figsize=(10, 8))
sns.boxplot(x="NU_NOTA_REDACAO", y = "Q006_RESPOSTA", data = dados_renda, order = renda_ordenada)
plt.title("Boxplot das notas da redação pela renda", fontsize = 16);
Quanto maior a renda do candidato, maior será seu desempenho. Esse argumento é nítido nos boxplots acima. Em quase todos os gráficos, o limite superior do gráfico de quem tem renda maior que 19.960 reais é o mesmo que o maior outlier de quem não tem nenhuma renda. Há de se observar o segundo quartil, ou a mediana, para cada nível de renda. De fato, há uma disparidade considerável e significativa em relação aos níveis.
Infelizmente, os gráficos demonstram a desigualdade social estruturada no próprio país, onde o acesso à informação e aos materiais é garantido àqueles que tem renda suficiente para suprir uma qualidade de ensino adequada e satisfatória.
Importante: A categoria 'De 8.982,01 até 9.980,00 reais' demonstra uma leve queda no desempenho em relação as outras categorias mais próximas.
Hipótese: há uma amostra pequena de candidatos nessa categoria
Análise de variância é a técnica estatística que permite avaliar afirmações sobre as médias de populações. A análise visa, fundamentalmente, verificar se existe uma diferença significativa entre as médias e se os fatores exercem influência em alguma variável dependente.
Fonte: https://pt.wikipedia.org/wiki/An%C3%A1lise_de_vari%C3%A2ncia
Para essa ocasião, estarei criando um modelo de ANOVA para realizar o teste se há diferença significativa entre as rendas. Para identificar, basta que o PR(>F) seja menor que 0,05 (nível de confiança para 95%) para contestar que há. (Hipótese Nula: Não há diferença significativa entre os grupos).
Irei utilizar as respostas pelas alternativas, a fim de tornar a visualização das tabelas mais clara. Portanto, estou deixando aqui o que significa cada resposta:
'A': 'Nenhuma renda.',
'B': 'Até R$ 998,00.',
'C' : 'De R$ 998,01 até R$ 1.497,00.',
'D' : 'De R$ 1.497,01 até R$ 1.996,00.',
'E' : 'De R$ 1.996,01 até R$ 2.495,00.',
'F': 'De R$ 2.495,01 até R$ 2.994,00.',
'G' :'De R$ 2.994,01 até R$ 3.992,00.',
'H' : 'De R$ 3.992,01 até R$ 4.990,00.',
'I' : 'De R$ 4.990,01 até R$ 5.988,00.',
'J' : 'De R$ 5.988,01 até R$ 6.986,00.',
'K' : 'De R$ 6.986,01 até R$ 7.984,00.',
'L' : 'De R$ 7.984,01 até R$ 8.982,00.',
'M' :'De R$ 8.982,01 até R$ 9.980,00.',
'N' : 'De R$ 9.980,01 até R$ 11.976,00.',
'O' : 'De R$ 11.976,01 até R$ 14.970,00.',
'P' : 'De R$ 14.970,01 até R$ 19.960,00.',
'Q' :'Mais de R$ 19.960,00.'
teste_renda = dados_renda.dropna(subset=['NU_NOTA_MT', 'NU_NOTA_CN', 'NU_NOTA_LC', 'NU_NOTA_CH']) #eliminando os valores NaN para tornar o modelo visível e saudável.
modelo1 = ols('NU_NOTA_MT ~ Q006_RESPOSTA', data = teste_renda).fit()
resultados1 = sm.stats.anova_lm(modelo1)
resultados1
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q006_RESPOSTA | 16.0 | 2.490306e+08 | 1.556441e+07 | 1679.511201 | 0.0 |
| Residual | 92522.0 | 8.574226e+08 | 9.267229e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de matemática. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_renda['NU_NOTA_MT'], teste_renda['Q006'])
resultado_teste1 = mc.tukeyhsd()
resultado_teste1.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| A | B | 7.0164 | 0.0026 | 1.2987 | 12.7341 | True |
| A | C | 27.4202 | 0.001 | 21.7058 | 33.1346 | True |
| A | D | 52.8561 | 0.001 | 46.525 | 59.1873 | True |
| A | E | 61.5389 | 0.001 | 55.1737 | 67.9041 | True |
| A | F | 85.2038 | 0.001 | 77.8465 | 92.561 | True |
| A | G | 90.7435 | 0.001 | 83.9201 | 97.567 | True |
| A | H | 116.0733 | 0.001 | 108.5743 | 123.5723 | True |
| A | I | 124.5797 | 0.001 | 116.4757 | 132.6836 | True |
| A | J | 132.0163 | 0.001 | 122.4194 | 141.6132 | True |
| A | K | 151.4937 | 0.001 | 140.6072 | 162.3802 | True |
| A | L | 165.3083 | 0.001 | 153.1551 | 177.4615 | True |
| A | M | 155.0078 | 0.001 | 142.7898 | 167.2257 | True |
| A | N | 175.1027 | 0.001 | 164.3654 | 185.8399 | True |
| A | O | 182.8204 | 0.001 | 171.4804 | 194.1604 | True |
| A | P | 203.4459 | 0.001 | 191.3614 | 215.5304 | True |
| A | Q | 214.2256 | 0.001 | 203.1034 | 225.3479 | True |
| B | C | 20.4038 | 0.001 | 17.2569 | 23.5507 | True |
| B | D | 45.8397 | 0.001 | 41.6765 | 50.0029 | True |
| B | E | 54.5225 | 0.001 | 50.3077 | 58.7373 | True |
| B | F | 78.1873 | 0.001 | 72.5857 | 83.789 | True |
| B | G | 83.7271 | 0.001 | 78.8478 | 88.6065 | True |
| B | H | 109.0569 | 0.001 | 103.2704 | 114.8434 | True |
| B | I | 117.5633 | 0.001 | 111.0117 | 124.1148 | True |
| B | J | 124.9999 | 0.001 | 116.6723 | 133.3275 | True |
| B | K | 144.4773 | 0.001 | 134.6913 | 154.2632 | True |
| B | L | 158.2919 | 0.001 | 147.1139 | 169.4699 | True |
| B | M | 147.9913 | 0.001 | 136.7429 | 159.2398 | True |
| B | N | 168.0863 | 0.001 | 158.4666 | 177.7059 | True |
| B | O | 175.804 | 0.001 | 165.516 | 186.092 | True |
| B | P | 196.4295 | 0.001 | 185.3262 | 207.5328 | True |
| B | Q | 207.2092 | 0.001 | 197.1617 | 217.2567 | True |
| C | D | 25.436 | 0.001 | 21.2773 | 29.5946 | True |
| C | E | 34.1188 | 0.001 | 29.9085 | 38.3291 | True |
| C | F | 57.7836 | 0.001 | 52.1853 | 63.3818 | True |
| C | G | 63.3234 | 0.001 | 58.4479 | 68.1988 | True |
| C | H | 88.6531 | 0.001 | 82.8699 | 94.4364 | True |
| C | I | 97.1595 | 0.001 | 90.6108 | 103.7082 | True |
| C | J | 104.5961 | 0.001 | 96.2708 | 112.9214 | True |
| C | K | 124.0735 | 0.001 | 114.2895 | 133.8575 | True |
| C | L | 137.8881 | 0.001 | 126.7118 | 149.0645 | True |
| C | M | 127.5876 | 0.001 | 116.3408 | 138.8343 | True |
| C | N | 147.6825 | 0.001 | 138.0649 | 157.3002 | True |
| C | O | 155.4002 | 0.001 | 145.114 | 165.6864 | True |
| C | P | 176.0257 | 0.001 | 164.9241 | 187.1274 | True |
| C | Q | 186.8055 | 0.001 | 176.7598 | 196.8511 | True |
| D | E | 8.6828 | 0.001 | 3.6672 | 13.6983 | True |
| D | F | 32.3476 | 0.001 | 26.1211 | 38.5741 | True |
| D | G | 37.8874 | 0.001 | 32.3018 | 43.473 | True |
| D | H | 63.2172 | 0.001 | 56.8238 | 69.6105 | True |
| D | I | 71.7235 | 0.001 | 64.6303 | 78.8168 | True |
| D | J | 79.1601 | 0.001 | 70.4 | 87.9203 | True |
| D | K | 98.6376 | 0.001 | 88.481 | 108.7941 | True |
| D | L | 112.4522 | 0.001 | 100.9483 | 123.9561 | True |
| D | M | 102.1516 | 0.001 | 90.5793 | 113.7239 | True |
| D | N | 122.2465 | 0.001 | 112.2501 | 132.243 | True |
| D | O | 129.9643 | 0.001 | 119.3231 | 140.6055 | True |
| D | P | 150.5898 | 0.001 | 139.1584 | 162.0211 | True |
| D | Q | 161.3695 | 0.001 | 150.9606 | 171.7783 | True |
| E | F | 23.6648 | 0.001 | 17.4037 | 29.926 | True |
| E | G | 29.2046 | 0.001 | 23.5804 | 34.8288 | True |
| E | H | 54.5344 | 0.001 | 48.1073 | 60.9614 | True |
| E | I | 63.0407 | 0.001 | 55.9171 | 70.1644 | True |
| E | J | 70.4774 | 0.001 | 61.6926 | 79.2621 | True |
| E | K | 89.9548 | 0.001 | 79.7769 | 100.1326 | True |
| E | L | 103.7694 | 0.001 | 92.2467 | 115.2921 | True |
| E | M | 93.4688 | 0.001 | 81.8779 | 105.0598 | True |
| E | N | 113.5638 | 0.001 | 103.5457 | 123.5818 | True |
| E | O | 121.2815 | 0.001 | 110.62 | 131.943 | True |
| E | P | 141.907 | 0.001 | 130.4568 | 153.3572 | True |
| E | Q | 152.6867 | 0.001 | 142.2571 | 163.1163 | True |
| F | G | 5.5398 | 0.2624 | -1.1867 | 12.2663 | False |
| F | H | 30.8695 | 0.001 | 23.4587 | 38.2804 | True |
| F | I | 39.3759 | 0.001 | 31.3534 | 47.3984 | True |
| F | J | 46.8125 | 0.001 | 37.2843 | 56.3407 | True |
| F | K | 66.2899 | 0.001 | 55.4639 | 77.1159 | True |
| F | L | 80.1045 | 0.001 | 68.0055 | 92.2036 | True |
| F | M | 69.804 | 0.001 | 57.6399 | 81.9681 | True |
| F | N | 89.8989 | 0.001 | 79.223 | 100.5748 | True |
| F | O | 97.6166 | 0.001 | 86.3348 | 108.8985 | True |
| F | P | 118.2421 | 0.001 | 106.2121 | 130.2722 | True |
| F | Q | 129.0219 | 0.001 | 117.9589 | 140.0849 | True |
| G | H | 25.3298 | 0.001 | 18.4486 | 32.211 | True |
| G | I | 33.8361 | 0.001 | 26.3002 | 41.3721 | True |
| G | J | 41.2727 | 0.001 | 32.1505 | 50.395 | True |
| G | K | 60.7502 | 0.001 | 50.2796 | 71.2207 | True |
| G | L | 74.5648 | 0.001 | 62.7828 | 86.3468 | True |
| G | M | 64.2642 | 0.001 | 52.4154 | 76.113 | True |
| G | N | 84.3591 | 0.001 | 74.0439 | 94.6744 | True |
| G | O | 92.0769 | 0.001 | 81.1356 | 103.0181 | True |
| G | P | 112.7024 | 0.001 | 100.9912 | 124.4135 | True |
| G | Q | 123.4821 | 0.001 | 112.7667 | 134.1975 | True |
| H | I | 8.5064 | 0.0304 | 0.3537 | 16.659 | True |
| H | J | 15.943 | 0.001 | 6.3049 | 25.581 | True |
| H | K | 35.4204 | 0.001 | 24.4976 | 46.3432 | True |
| H | L | 49.235 | 0.001 | 37.0493 | 61.4207 | True |
| H | M | 38.9345 | 0.001 | 26.6841 | 51.1848 | True |
| H | N | 59.0294 | 0.001 | 48.2553 | 69.8034 | True |
| H | O | 66.7471 | 0.001 | 55.3723 | 78.1219 | True |
| H | P | 87.3726 | 0.001 | 75.2554 | 99.4898 | True |
| H | Q | 98.1523 | 0.001 | 86.9945 | 109.3101 | True |
| I | J | 7.4366 | 0.4728 | -2.6793 | 17.5525 | False |
| I | K | 26.914 | 0.001 | 15.5674 | 38.2607 | True |
| I | L | 40.7286 | 0.001 | 28.1616 | 53.2957 | True |
| I | M | 30.4281 | 0.001 | 17.7984 | 43.0578 | True |
| I | N | 50.523 | 0.001 | 39.3195 | 61.7266 | True |
| I | O | 58.2407 | 0.001 | 46.4583 | 70.0232 | True |
| I | P | 78.8662 | 0.001 | 66.3656 | 91.3669 | True |
| I | Q | 89.646 | 0.001 | 78.0729 | 101.219 | True |
| J | K | 19.4774 | 0.001 | 7.0206 | 31.9342 | True |
| J | L | 33.292 | 0.001 | 19.7142 | 46.8698 | True |
| J | M | 22.9915 | 0.001 | 9.3557 | 36.6273 | True |
| J | N | 43.0864 | 0.001 | 30.7598 | 55.413 | True |
| J | O | 50.8041 | 0.001 | 37.9491 | 63.6591 | True |
| J | P | 71.4296 | 0.001 | 57.9133 | 84.946 | True |
| J | Q | 82.2093 | 0.001 | 69.546 | 94.8727 | True |
| K | L | 13.8146 | 0.0844 | -0.7034 | 28.3326 | False |
| K | M | 3.5141 | 0.9 | -11.0582 | 18.0863 | False |
| K | N | 23.609 | 0.001 | 10.2538 | 36.9642 | True |
| K | O | 31.3267 | 0.001 | 17.4823 | 45.1711 | True |
| K | P | 51.9522 | 0.001 | 37.4917 | 66.4128 | True |
| K | Q | 62.7319 | 0.001 | 49.0653 | 76.3986 | True |
| L | M | -10.3005 | 0.6368 | -25.8419 | 5.2408 | False |
| L | N | 9.7944 | 0.5983 | -4.612 | 24.2008 | False |
| L | O | 17.5121 | 0.0053 | 2.651 | 32.3732 | True |
| L | P | 38.1376 | 0.001 | 22.7009 | 53.5743 | True |
| L | Q | 48.9173 | 0.001 | 34.2217 | 63.6129 | True |
| M | N | 20.0949 | 0.001 | 5.6338 | 34.556 | True |
| M | O | 27.8126 | 0.001 | 12.8986 | 42.7267 | True |
| M | P | 48.4381 | 0.001 | 32.9504 | 63.9259 | True |
| M | Q | 59.2179 | 0.001 | 44.4687 | 73.9671 | True |
| N | O | 7.7177 | 0.8633 | -6.0096 | 21.4451 | False |
| N | P | 28.3432 | 0.001 | 13.9947 | 42.6917 | True |
| N | Q | 39.1229 | 0.001 | 25.5749 | 52.671 | True |
| O | P | 20.6255 | 0.001 | 5.8205 | 35.4305 | True |
| O | Q | 31.4052 | 0.001 | 17.3747 | 45.4357 | True |
| P | Q | 10.7797 | 0.4698 | -3.8591 | 25.4186 | False |
Em alguns casos não há diferença sifnigicativa na nota de matemática. São as rendas: F e G, I e J, J e K, K e L, K e M, L e M, L e N, N e O, P e Q. Ao passo que as categorias vão aumentando, maior será a combinação entre elas. De fato, são muitas rendas que, se comparadas entre si, possuem uma diferença significativa. Entretanto, as aqui listadas não possuem nenhuma diferença significativa se comparadas entre si.
modelo2 = ols('NU_NOTA_CN ~ Q006_RESPOSTA', data = teste_renda).fit()
resultados2 = sm.stats.anova_lm(modelo2)
resultados2
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q006_RESPOSTA | 16.0 | 1.075993e+08 | 6.724953e+06 | 1445.678168 | 0.0 |
| Residual | 92522.0 | 4.303905e+08 | 4.651764e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências da natureza. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_renda['NU_NOTA_CN'], teste_renda['Q006'])
resultado_teste2 = mc.tukeyhsd()
resultado_teste2.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| A | B | 3.0714 | 0.4149 | -0.9796 | 7.1223 | False |
| A | C | 19.538 | 0.001 | 15.4894 | 23.5866 | True |
| A | D | 34.7863 | 0.001 | 30.3008 | 39.2719 | True |
| A | E | 42.578 | 0.001 | 38.0683 | 47.0876 | True |
| A | F | 54.7143 | 0.001 | 49.5017 | 59.9268 | True |
| A | G | 60.9888 | 0.001 | 56.1544 | 65.8231 | True |
| A | H | 78.0575 | 0.001 | 72.7445 | 83.3704 | True |
| A | I | 82.7573 | 0.001 | 77.0157 | 88.4988 | True |
| A | J | 90.1025 | 0.001 | 83.3032 | 96.9018 | True |
| A | K | 101.0449 | 0.001 | 93.332 | 108.7579 | True |
| A | L | 106.7804 | 0.001 | 98.17 | 115.3908 | True |
| A | M | 103.2076 | 0.001 | 94.5513 | 111.8639 | True |
| A | N | 115.6072 | 0.001 | 108.0 | 123.2145 | True |
| A | O | 116.924 | 0.001 | 108.8897 | 124.9583 | True |
| A | P | 129.2398 | 0.001 | 120.678 | 137.8015 | True |
| A | Q | 133.7066 | 0.001 | 125.8266 | 141.5866 | True |
| B | C | 16.4666 | 0.001 | 14.2371 | 18.6962 | True |
| B | D | 31.7149 | 0.001 | 28.7654 | 34.6645 | True |
| B | E | 39.5066 | 0.001 | 36.5204 | 42.4927 | True |
| B | F | 51.6429 | 0.001 | 47.6742 | 55.6116 | True |
| B | G | 57.9174 | 0.001 | 54.4604 | 61.3744 | True |
| B | H | 74.9861 | 0.001 | 70.8864 | 79.0858 | True |
| B | I | 79.6859 | 0.001 | 75.0442 | 84.3276 | True |
| B | J | 87.0311 | 0.001 | 81.1311 | 92.9311 | True |
| B | K | 97.9736 | 0.001 | 91.0403 | 104.9068 | True |
| B | L | 103.7091 | 0.001 | 95.7895 | 111.6286 | True |
| B | M | 100.1362 | 0.001 | 92.1668 | 108.1056 | True |
| B | N | 112.5358 | 0.001 | 105.7204 | 119.3513 | True |
| B | O | 113.8526 | 0.001 | 106.5636 | 121.1416 | True |
| B | P | 126.1684 | 0.001 | 118.3018 | 134.035 | True |
| B | Q | 130.6352 | 0.001 | 123.5166 | 137.7538 | True |
| C | D | 15.2483 | 0.001 | 12.302 | 18.1947 | True |
| C | E | 23.04 | 0.001 | 20.057 | 26.0229 | True |
| C | F | 35.1763 | 0.001 | 31.21 | 39.1426 | True |
| C | G | 41.4508 | 0.001 | 37.9966 | 44.905 | True |
| C | H | 58.5195 | 0.001 | 54.4221 | 62.6168 | True |
| C | I | 63.2193 | 0.001 | 58.5796 | 67.8589 | True |
| C | J | 70.5645 | 0.001 | 64.6661 | 76.4629 | True |
| C | K | 81.507 | 0.001 | 74.5751 | 88.4388 | True |
| C | L | 87.2424 | 0.001 | 79.3241 | 95.1608 | True |
| C | M | 83.6696 | 0.001 | 75.7014 | 91.6378 | True |
| C | N | 96.0692 | 0.001 | 89.2552 | 102.8832 | True |
| C | O | 97.386 | 0.001 | 90.0983 | 104.6737 | True |
| C | P | 109.7018 | 0.001 | 101.8364 | 117.5672 | True |
| C | Q | 114.1686 | 0.001 | 107.0514 | 121.2859 | True |
| D | E | 7.7916 | 0.001 | 4.2382 | 11.3451 | True |
| D | F | 19.9279 | 0.001 | 15.5165 | 24.3394 | True |
| D | G | 26.2025 | 0.001 | 22.2451 | 30.1598 | True |
| D | H | 43.2711 | 0.001 | 38.7415 | 47.8008 | True |
| D | I | 47.9709 | 0.001 | 42.9454 | 52.9964 | True |
| D | J | 55.3162 | 0.001 | 49.1097 | 61.5226 | True |
| D | K | 66.2586 | 0.001 | 59.0628 | 73.4545 | True |
| D | L | 71.9941 | 0.001 | 63.8437 | 80.1445 | True |
| D | M | 68.4212 | 0.001 | 60.2224 | 76.6201 | True |
| D | N | 80.8209 | 0.001 | 73.7385 | 87.9033 | True |
| D | O | 82.1377 | 0.001 | 74.5985 | 89.6769 | True |
| D | P | 94.4534 | 0.001 | 86.3545 | 102.5524 | True |
| D | Q | 98.9203 | 0.001 | 91.5457 | 106.2949 | True |
| E | F | 12.1363 | 0.001 | 7.7004 | 16.5723 | True |
| E | G | 18.4108 | 0.001 | 14.4261 | 22.3955 | True |
| E | H | 35.4795 | 0.001 | 30.926 | 40.033 | True |
| E | I | 40.1793 | 0.001 | 35.1323 | 45.2264 | True |
| E | J | 47.5245 | 0.001 | 41.3006 | 53.7485 | True |
| E | K | 58.467 | 0.001 | 51.2561 | 65.6779 | True |
| E | L | 64.2025 | 0.001 | 56.0388 | 72.3662 | True |
| E | M | 60.6296 | 0.001 | 52.4175 | 68.8417 | True |
| E | N | 73.0293 | 0.001 | 65.9316 | 80.1269 | True |
| E | O | 74.346 | 0.001 | 66.7925 | 81.8996 | True |
| E | P | 86.6618 | 0.001 | 78.5494 | 94.7742 | True |
| E | Q | 91.1286 | 0.001 | 83.7394 | 98.5179 | True |
| F | G | 6.2745 | 0.001 | 1.5089 | 11.0402 | True |
| F | H | 23.3432 | 0.001 | 18.0927 | 28.5937 | True |
| F | I | 28.043 | 0.001 | 22.3591 | 33.7268 | True |
| F | J | 35.3882 | 0.001 | 28.6376 | 42.1388 | True |
| F | K | 46.3307 | 0.001 | 38.6606 | 54.0008 | True |
| F | L | 52.0662 | 0.001 | 43.4941 | 60.6382 | True |
| F | M | 48.4933 | 0.001 | 39.8752 | 57.1114 | True |
| F | N | 60.8929 | 0.001 | 53.3292 | 68.4567 | True |
| F | O | 62.2097 | 0.001 | 54.2166 | 70.2028 | True |
| F | P | 74.5255 | 0.001 | 66.0023 | 83.0486 | True |
| F | Q | 78.9923 | 0.001 | 71.1543 | 86.8304 | True |
| G | H | 17.0687 | 0.001 | 12.1934 | 21.9439 | True |
| G | I | 21.7685 | 0.001 | 16.4293 | 27.1076 | True |
| G | J | 29.1137 | 0.001 | 22.6506 | 35.5768 | True |
| G | K | 40.0562 | 0.001 | 32.6379 | 47.4744 | True |
| G | L | 45.7916 | 0.001 | 37.4442 | 54.1391 | True |
| G | M | 42.2188 | 0.001 | 33.824 | 50.6135 | True |
| G | N | 54.6184 | 0.001 | 47.3102 | 61.9267 | True |
| G | O | 55.9352 | 0.001 | 48.1834 | 63.687 | True |
| G | P | 68.251 | 0.001 | 59.9537 | 76.5482 | True |
| G | Q | 72.7178 | 0.001 | 65.126 | 80.3096 | True |
| H | I | 4.6998 | 0.2828 | -1.0763 | 10.4759 | False |
| H | J | 12.045 | 0.001 | 5.2166 | 18.8735 | True |
| H | K | 22.9875 | 0.001 | 15.2488 | 30.7262 | True |
| H | L | 28.723 | 0.001 | 20.0895 | 37.3564 | True |
| H | M | 25.1501 | 0.001 | 16.4709 | 33.8293 | True |
| H | N | 37.5498 | 0.001 | 29.9164 | 45.1831 | True |
| H | O | 38.8665 | 0.001 | 30.8076 | 46.9255 | True |
| H | P | 51.1823 | 0.001 | 42.5974 | 59.7672 | True |
| H | Q | 55.6491 | 0.001 | 47.744 | 63.5543 | True |
| I | J | 7.3452 | 0.0378 | 0.1782 | 14.5122 | True |
| I | K | 18.2877 | 0.001 | 10.2487 | 26.3267 | True |
| I | L | 24.0232 | 0.001 | 15.1195 | 32.9268 | True |
| I | M | 20.4503 | 0.001 | 11.5023 | 29.3983 | True |
| I | N | 32.85 | 0.001 | 24.9123 | 40.7876 | True |
| I | O | 34.1667 | 0.001 | 25.819 | 42.5145 | True |
| I | P | 46.4825 | 0.001 | 37.6259 | 55.3391 | True |
| I | Q | 50.9493 | 0.001 | 42.75 | 59.1487 | True |
| J | K | 10.9425 | 0.0022 | 2.1169 | 19.768 | True |
| J | L | 16.6779 | 0.001 | 7.0582 | 26.2977 | True |
| J | M | 13.1051 | 0.001 | 3.4442 | 22.7659 | True |
| J | N | 25.5047 | 0.001 | 16.7714 | 34.238 | True |
| J | O | 26.8215 | 0.001 | 17.7138 | 35.9292 | True |
| J | P | 39.1373 | 0.001 | 29.5611 | 48.7135 | True |
| J | Q | 43.6041 | 0.001 | 34.6322 | 52.576 | True |
| K | L | 5.7355 | 0.8737 | -4.5504 | 16.0213 | False |
| K | M | 2.1626 | 0.9 | -8.1617 | 12.4869 | False |
| K | N | 14.5623 | 0.001 | 5.1002 | 24.0243 | True |
| K | O | 15.879 | 0.001 | 6.0704 | 25.6877 | True |
| K | P | 28.1948 | 0.001 | 17.9496 | 38.44 | True |
| K | Q | 32.6617 | 0.001 | 22.979 | 42.3443 | True |
| L | M | -3.5729 | 0.9 | -14.5838 | 7.4381 | False |
| L | N | 8.8268 | 0.1882 | -1.38 | 19.0336 | False |
| L | O | 10.1436 | 0.0747 | -0.3854 | 20.6725 | False |
| L | P | 22.4593 | 0.001 | 11.5226 | 33.3961 | True |
| L | Q | 26.9262 | 0.001 | 16.5145 | 37.3379 | True |
| M | N | 12.3996 | 0.0034 | 2.1541 | 22.6452 | True |
| M | O | 13.7164 | 0.001 | 3.1499 | 24.2829 | True |
| M | P | 26.0322 | 0.001 | 15.0593 | 37.0051 | True |
| M | Q | 30.499 | 0.001 | 20.0494 | 40.9487 | True |
| N | O | 1.3168 | 0.9 | -8.4089 | 11.0425 | False |
| N | P | 13.6325 | 0.001 | 3.4667 | 23.7983 | True |
| N | Q | 18.0994 | 0.001 | 8.5007 | 27.698 | True |
| O | P | 12.3158 | 0.0056 | 1.8266 | 22.8049 | True |
| O | Q | 16.7826 | 0.001 | 6.8421 | 26.7231 | True |
| P | Q | 4.4668 | 0.9 | -5.9046 | 14.8383 | False |
Em alguns casos não há diferença sifnigicativa na nota de ciências da natureza. São as rendas: A e B, H e I, L e M, L e N, L e O, N e O, P e Q. Ao passo que as categorias vão aumentando, maior será a combinação entre elas. De fato, são muitas rendas que, se comparadas entre si, possuem uma diferença significativa. Entretanto, as aqui listadas não possuem nenhuma diferença significativa se comparadas entre si.
modelo3 = ols('NU_NOTA_LC ~ Q006_RESPOSTA', data = teste_renda).fit()
resultados3 = sm.stats.anova_lm(modelo3)
resultados3
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q006_RESPOSTA | 16.0 | 6.426188e+07 | 4.016368e+06 | 1220.083428 | 0.0 |
| Residual | 92522.0 | 3.045713e+08 | 3.291880e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de linguagens e códigos. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_renda['NU_NOTA_LC'], teste_renda['Q006'])
resultado_teste3 = mc.tukeyhsd()
resultado_teste3.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| A | B | 6.6836 | 0.001 | 3.2759 | 10.0914 | True |
| A | C | 24.4544 | 0.001 | 21.0486 | 27.8602 | True |
| A | D | 37.6905 | 0.001 | 33.9171 | 41.4639 | True |
| A | E | 43.1907 | 0.001 | 39.397 | 46.9843 | True |
| A | F | 53.8683 | 0.001 | 49.4834 | 58.2533 | True |
| A | G | 56.7117 | 0.001 | 52.6449 | 60.7785 | True |
| A | H | 68.5281 | 0.001 | 64.0587 | 72.9975 | True |
| A | I | 70.0378 | 0.001 | 65.2078 | 74.8678 | True |
| A | J | 74.6497 | 0.001 | 68.93 | 80.3695 | True |
| A | K | 80.6071 | 0.001 | 74.1187 | 87.0955 | True |
| A | L | 85.9441 | 0.001 | 78.7008 | 93.1875 | True |
| A | M | 84.8184 | 0.001 | 77.5365 | 92.1003 | True |
| A | N | 88.6229 | 0.001 | 82.2234 | 95.0223 | True |
| A | O | 91.0601 | 0.001 | 84.3015 | 97.8188 | True |
| A | P | 98.1106 | 0.001 | 90.9082 | 105.313 | True |
| A | Q | 103.2179 | 0.001 | 96.589 | 109.8468 | True |
| B | C | 17.7707 | 0.001 | 15.8952 | 19.6463 | True |
| B | D | 31.0069 | 0.001 | 28.5256 | 33.4881 | True |
| B | E | 36.507 | 0.001 | 33.995 | 39.019 | True |
| B | F | 47.1847 | 0.001 | 43.8461 | 50.5232 | True |
| B | G | 50.028 | 0.001 | 47.1199 | 52.9361 | True |
| B | H | 61.8445 | 0.001 | 58.3957 | 65.2932 | True |
| B | I | 63.3541 | 0.001 | 59.4494 | 67.2589 | True |
| B | J | 67.9661 | 0.001 | 63.0028 | 72.9293 | True |
| B | K | 73.9235 | 0.001 | 68.091 | 79.7559 | True |
| B | L | 79.2605 | 0.001 | 72.5984 | 85.9226 | True |
| B | M | 78.1347 | 0.001 | 71.4307 | 84.8388 | True |
| B | N | 81.9392 | 0.001 | 76.2059 | 87.6725 | True |
| B | O | 84.3765 | 0.001 | 78.2448 | 90.5082 | True |
| B | P | 91.427 | 0.001 | 84.8094 | 98.0446 | True |
| B | Q | 96.5342 | 0.001 | 90.5459 | 102.5226 | True |
| C | D | 13.2361 | 0.001 | 10.7576 | 15.7147 | True |
| C | E | 18.7363 | 0.001 | 16.2269 | 21.2456 | True |
| C | F | 29.4139 | 0.001 | 26.0774 | 32.7505 | True |
| C | G | 32.2573 | 0.001 | 29.3515 | 35.1631 | True |
| C | H | 44.0737 | 0.001 | 40.6269 | 47.5206 | True |
| C | I | 45.5834 | 0.001 | 41.6804 | 49.4864 | True |
| C | J | 50.1953 | 0.001 | 45.2334 | 55.1573 | True |
| C | K | 56.1527 | 0.001 | 50.3214 | 61.984 | True |
| C | L | 61.4898 | 0.001 | 54.8287 | 68.1509 | True |
| C | M | 60.364 | 0.001 | 53.6609 | 67.0671 | True |
| C | N | 64.1685 | 0.001 | 58.4363 | 69.9006 | True |
| C | O | 66.6057 | 0.001 | 60.4751 | 72.7363 | True |
| C | P | 73.6562 | 0.001 | 67.0396 | 80.2728 | True |
| C | Q | 78.7635 | 0.001 | 72.7763 | 84.7507 | True |
| D | E | 5.5002 | 0.001 | 2.5109 | 8.4894 | True |
| D | F | 16.1778 | 0.001 | 12.4668 | 19.8888 | True |
| D | G | 19.0212 | 0.001 | 15.6921 | 22.3502 | True |
| D | H | 30.8376 | 0.001 | 27.0272 | 34.6481 | True |
| D | I | 32.3473 | 0.001 | 28.1197 | 36.5749 | True |
| D | J | 36.9592 | 0.001 | 31.7382 | 42.1803 | True |
| D | K | 42.9166 | 0.001 | 36.8633 | 48.9699 | True |
| D | L | 48.2536 | 0.001 | 41.3973 | 55.11 | True |
| D | M | 47.1279 | 0.001 | 40.2308 | 54.025 | True |
| D | N | 50.9324 | 0.001 | 44.9745 | 56.8903 | True |
| D | O | 53.3696 | 0.001 | 47.0275 | 59.7118 | True |
| D | P | 60.4201 | 0.001 | 53.607 | 67.2332 | True |
| D | Q | 65.5274 | 0.001 | 59.3237 | 71.7311 | True |
| E | F | 10.6776 | 0.001 | 6.946 | 14.4093 | True |
| E | G | 13.521 | 0.001 | 10.169 | 16.873 | True |
| E | H | 25.3375 | 0.001 | 21.5069 | 29.168 | True |
| E | I | 26.8471 | 0.001 | 22.6014 | 31.0928 | True |
| E | J | 31.4591 | 0.001 | 26.2233 | 36.6948 | True |
| E | K | 37.4164 | 0.001 | 31.3504 | 43.4824 | True |
| E | L | 42.7535 | 0.001 | 35.886 | 49.621 | True |
| E | M | 41.6277 | 0.001 | 34.7195 | 48.536 | True |
| E | N | 45.4322 | 0.001 | 39.4615 | 51.403 | True |
| E | O | 47.8695 | 0.001 | 41.5152 | 54.2237 | True |
| E | P | 54.9199 | 0.001 | 48.0956 | 61.7443 | True |
| E | Q | 60.0272 | 0.001 | 53.8112 | 66.2433 | True |
| F | G | 2.8434 | 0.5322 | -1.1656 | 6.8524 | False |
| F | H | 14.6598 | 0.001 | 10.2429 | 19.0767 | True |
| F | I | 16.1695 | 0.001 | 11.3881 | 20.9509 | True |
| F | J | 20.7814 | 0.001 | 15.1026 | 26.4602 | True |
| F | K | 26.7388 | 0.001 | 20.2865 | 33.1911 | True |
| F | L | 32.0758 | 0.001 | 24.8648 | 39.2869 | True |
| F | M | 30.9501 | 0.001 | 23.7003 | 38.1999 | True |
| F | N | 34.7546 | 0.001 | 28.3917 | 41.1174 | True |
| F | O | 37.1918 | 0.001 | 30.4678 | 43.9158 | True |
| F | P | 44.2423 | 0.001 | 37.0724 | 51.4122 | True |
| F | Q | 49.3496 | 0.001 | 42.756 | 55.9432 | True |
| G | H | 11.8164 | 0.001 | 7.7152 | 15.9176 | True |
| G | I | 13.3261 | 0.001 | 8.8347 | 17.8175 | True |
| G | J | 17.9381 | 0.001 | 12.5012 | 23.3749 | True |
| G | K | 23.8954 | 0.001 | 17.655 | 30.1359 | True |
| G | L | 29.2325 | 0.001 | 22.2104 | 36.2546 | True |
| G | M | 28.1067 | 0.001 | 21.0448 | 35.1686 | True |
| G | N | 31.9112 | 0.001 | 25.7633 | 38.0591 | True |
| G | O | 34.3484 | 0.001 | 27.8274 | 40.8694 | True |
| G | P | 41.3989 | 0.001 | 34.4191 | 48.3788 | True |
| G | Q | 46.5062 | 0.001 | 40.1198 | 52.8926 | True |
| H | I | 1.5097 | 0.9 | -3.3493 | 6.3687 | False |
| H | J | 6.1216 | 0.0232 | 0.3773 | 11.8659 | True |
| H | K | 12.079 | 0.001 | 5.569 | 18.589 | True |
| H | L | 17.416 | 0.001 | 10.1533 | 24.6787 | True |
| H | M | 16.2903 | 0.001 | 8.9891 | 23.5915 | True |
| H | N | 20.0948 | 0.001 | 13.6734 | 26.5161 | True |
| H | O | 22.532 | 0.001 | 15.7526 | 29.3114 | True |
| H | P | 29.5825 | 0.001 | 22.3606 | 36.8044 | True |
| H | Q | 34.6898 | 0.001 | 28.0397 | 41.3398 | True |
| I | J | 4.6119 | 0.3974 | -1.4171 | 10.641 | False |
| I | K | 10.5693 | 0.001 | 3.8067 | 17.3319 | True |
| I | L | 15.9064 | 0.001 | 8.4164 | 23.3963 | True |
| I | M | 14.7806 | 0.001 | 7.2533 | 22.3079 | True |
| I | N | 18.5851 | 0.001 | 11.9078 | 25.2624 | True |
| I | O | 21.0223 | 0.001 | 14.0 | 28.0447 | True |
| I | P | 28.0728 | 0.001 | 20.6224 | 35.5232 | True |
| I | Q | 33.1801 | 0.001 | 26.2826 | 40.0776 | True |
| J | K | 5.9574 | 0.3067 | -1.4669 | 13.3817 | False |
| J | L | 11.2944 | 0.001 | 3.202 | 19.3868 | True |
| J | M | 10.1687 | 0.0018 | 2.0417 | 18.2956 | True |
| J | N | 13.9731 | 0.001 | 6.6265 | 21.3198 | True |
| J | O | 16.4104 | 0.001 | 8.7488 | 24.072 | True |
| J | P | 23.4609 | 0.001 | 15.4051 | 31.5166 | True |
| J | Q | 28.5682 | 0.001 | 21.0208 | 36.1155 | True |
| K | L | 5.337 | 0.7404 | -3.3157 | 13.9898 | False |
| K | M | 4.2113 | 0.9 | -4.4738 | 12.8964 | False |
| K | N | 8.0158 | 0.0463 | 0.0561 | 15.9755 | True |
| K | O | 10.453 | 0.0014 | 2.2017 | 18.7043 | True |
| K | P | 17.5035 | 0.001 | 8.885 | 26.122 | True |
| K | Q | 22.6108 | 0.001 | 14.4655 | 30.7561 | True |
| L | M | -1.1258 | 0.9 | -10.3885 | 8.1369 | False |
| L | N | 2.6787 | 0.9 | -5.9075 | 11.265 | False |
| L | O | 5.116 | 0.8286 | -3.7412 | 13.9732 | False |
| L | P | 12.1665 | 0.001 | 2.9662 | 21.3667 | True |
| L | Q | 17.2737 | 0.001 | 8.5152 | 26.0323 | True |
| M | N | 3.8045 | 0.9 | -4.8143 | 12.4233 | False |
| M | O | 6.2417 | 0.548 | -2.6471 | 15.1305 | False |
| M | P | 13.2922 | 0.001 | 4.0615 | 22.5229 | True |
| M | Q | 18.3995 | 0.001 | 9.609 | 27.1901 | True |
| N | O | 2.4372 | 0.9 | -5.7443 | 10.6188 | False |
| N | P | 9.4877 | 0.0134 | 0.936 | 18.0395 | True |
| N | Q | 14.595 | 0.001 | 6.5204 | 22.6697 | True |
| O | P | 7.0505 | 0.314 | -1.7733 | 15.8743 | False |
| O | Q | 12.1578 | 0.001 | 3.7956 | 20.52 | True |
| P | Q | 5.1073 | 0.8111 | -3.6175 | 13.8321 | False |
Em alguns casos não há diferença sifnigicativa na nota de linguagens e códigos. São as rendas: F e G, H e I, I e J, J e K, K e L, K e M, L e M, L e N, L e O, M e N, M e O, N e O, O e P, P e Q. Ao passo que as categorias vão aumentando, maior será a combinação entre elas. De fato, são muitas rendas que, se comparadas entre si, possuem uma diferença significativa. Entretanto, as aqui listadas não possuem nenhuma diferença significativa se comparadas entre si.
modelo4 = ols('NU_NOTA_CH ~ Q006_RESPOSTA', data = teste_renda).fit()
resultados4 = sm.stats.anova_lm(modelo4)
resultados4
| df | sum_sq | mean_sq | F | PR(>F) | |
|---|---|---|---|---|---|
| Q006_RESPOSTA | 16.0 | 1.067658e+08 | 6.672863e+06 | 1217.681043 | 0.0 |
| Residual | 92522.0 | 5.070184e+08 | 5.479976e+03 | NaN | NaN |
Rejeitar a hipótese nula. O resultado demonstra que sim, há diferença significativa entre os grupos nas notas de ciências humanas. (afirmando o argumento da seção acima)
mc = MultiComparison(teste_renda['NU_NOTA_CH'], teste_renda['Q006'])
resultado_teste4 = mc.tukeyhsd()
resultado_teste4.summary()
| group1 | group2 | meandiff | p-adj | lower | upper | reject |
|---|---|---|---|---|---|---|
| A | B | 5.3126 | 0.0034 | 0.9158 | 9.7094 | True |
| A | C | 24.8312 | 0.001 | 20.437 | 29.2255 | True |
| A | D | 41.4753 | 0.001 | 36.6068 | 46.3438 | True |
| A | E | 47.4347 | 0.001 | 42.54 | 52.3294 | True |
| A | F | 61.9913 | 0.001 | 56.3337 | 67.6489 | True |
| A | G | 66.6491 | 0.001 | 61.402 | 71.8962 | True |
| A | H | 83.0199 | 0.001 | 77.2533 | 88.7865 | True |
| A | I | 86.5663 | 0.001 | 80.3345 | 92.7981 | True |
| A | J | 90.4165 | 0.001 | 83.0367 | 97.7963 | True |
| A | K | 102.3365 | 0.001 | 93.965 | 110.708 | True |
| A | L | 108.3221 | 0.001 | 98.9766 | 117.6677 | True |
| A | M | 104.0733 | 0.001 | 94.678 | 113.4687 | True |
| A | N | 113.2547 | 0.001 | 104.998 | 121.5115 | True |
| A | O | 114.5036 | 0.001 | 105.7834 | 123.2238 | True |
| A | P | 130.8068 | 0.001 | 121.5141 | 140.0996 | True |
| A | Q | 134.5418 | 0.001 | 125.9891 | 143.0946 | True |
| B | C | 19.5186 | 0.001 | 17.0987 | 21.9385 | True |
| B | D | 36.1627 | 0.001 | 32.9613 | 39.3641 | True |
| B | E | 42.1221 | 0.001 | 38.881 | 45.3632 | True |
| B | F | 56.6787 | 0.001 | 52.3712 | 60.9862 | True |
| B | G | 61.3365 | 0.001 | 57.5844 | 65.0886 | True |
| B | H | 77.7073 | 0.001 | 73.2576 | 82.157 | True |
| B | I | 81.2537 | 0.001 | 76.2157 | 86.2917 | True |
| B | J | 85.1039 | 0.001 | 78.7001 | 91.5076 | True |
| B | K | 97.0239 | 0.001 | 89.4987 | 104.5491 | True |
| B | L | 103.0095 | 0.001 | 94.4138 | 111.6052 | True |
| B | M | 98.7607 | 0.001 | 90.1109 | 107.4105 | True |
| B | N | 107.9421 | 0.001 | 100.5448 | 115.3394 | True |
| B | O | 109.191 | 0.001 | 101.2797 | 117.1023 | True |
| B | P | 125.4942 | 0.001 | 116.956 | 134.0324 | True |
| B | Q | 129.2292 | 0.001 | 121.5029 | 136.9556 | True |
| C | D | 16.644 | 0.001 | 13.4461 | 19.842 | True |
| C | E | 22.6035 | 0.001 | 19.3659 | 25.8411 | True |
| C | F | 37.1601 | 0.001 | 32.8551 | 41.465 | True |
| C | G | 41.8179 | 0.001 | 38.0687 | 45.567 | True |
| C | H | 58.1887 | 0.001 | 53.7415 | 62.6359 | True |
| C | I | 61.7351 | 0.001 | 56.6993 | 66.7709 | True |
| C | J | 65.5853 | 0.001 | 59.1833 | 71.9873 | True |
| C | K | 77.5053 | 0.001 | 69.9816 | 85.029 | True |
| C | L | 83.4909 | 0.001 | 74.8965 | 92.0853 | True |
| C | M | 79.2421 | 0.001 | 70.5936 | 87.8906 | True |
| C | N | 88.4235 | 0.001 | 81.0277 | 95.8193 | True |
| C | O | 89.6724 | 0.001 | 81.7625 | 97.5822 | True |
| C | P | 105.9756 | 0.001 | 97.4387 | 114.5125 | True |
| C | Q | 109.7106 | 0.001 | 101.9857 | 117.4355 | True |
| D | E | 5.9595 | 0.001 | 2.1026 | 9.8163 | True |
| D | F | 20.516 | 0.001 | 15.728 | 25.3041 | True |
| D | G | 25.1738 | 0.001 | 20.8786 | 29.4691 | True |
| D | H | 41.5446 | 0.001 | 36.6283 | 46.461 | True |
| D | I | 45.091 | 0.001 | 39.6365 | 50.5456 | True |
| D | J | 48.9412 | 0.001 | 42.2049 | 55.6776 | True |
| D | K | 60.8613 | 0.001 | 53.0511 | 68.6714 | True |
| D | L | 66.8469 | 0.001 | 58.0006 | 75.6931 | True |
| D | M | 62.598 | 0.001 | 53.6992 | 71.4969 | True |
| D | N | 71.7795 | 0.001 | 64.0924 | 79.4665 | True |
| D | O | 73.0283 | 0.001 | 64.8455 | 81.2112 | True |
| D | P | 89.3315 | 0.001 | 80.5411 | 98.122 | True |
| D | Q | 93.0666 | 0.001 | 85.0624 | 101.0707 | True |
| E | F | 14.5566 | 0.001 | 9.7419 | 19.3712 | True |
| E | G | 19.2144 | 0.001 | 14.8895 | 23.5393 | True |
| E | H | 35.5852 | 0.001 | 30.6429 | 40.5275 | True |
| E | I | 39.1316 | 0.001 | 33.6536 | 44.6095 | True |
| E | J | 42.9818 | 0.001 | 36.2265 | 49.7371 | True |
| E | K | 54.9018 | 0.001 | 47.0753 | 62.7283 | True |
| E | L | 60.8874 | 0.001 | 52.0267 | 69.7481 | True |
| E | M | 56.6386 | 0.001 | 47.7254 | 65.5518 | True |
| E | N | 65.82 | 0.001 | 58.1164 | 73.5237 | True |
| E | O | 67.0689 | 0.001 | 58.8704 | 75.2673 | True |
| E | P | 83.3721 | 0.001 | 74.5671 | 92.1771 | True |
| E | Q | 87.1071 | 0.001 | 79.087 | 95.1272 | True |
| F | G | 4.6578 | 0.1369 | -0.5147 | 9.8303 | False |
| F | H | 21.0286 | 0.001 | 15.3298 | 26.7274 | True |
| F | I | 24.575 | 0.001 | 18.4059 | 30.7441 | True |
| F | J | 28.4252 | 0.001 | 21.0982 | 35.7522 | True |
| F | K | 40.3452 | 0.001 | 32.0203 | 48.6702 | True |
| F | L | 46.3308 | 0.001 | 37.027 | 55.6347 | True |
| F | M | 42.082 | 0.001 | 32.7281 | 51.4359 | True |
| F | N | 51.2634 | 0.001 | 43.0539 | 59.473 | True |
| F | O | 52.5123 | 0.001 | 43.8368 | 61.1878 | True |
| F | P | 68.8155 | 0.001 | 59.5647 | 78.0663 | True |
| F | Q | 72.5505 | 0.001 | 64.0433 | 81.0578 | True |
| G | H | 16.3708 | 0.001 | 11.0793 | 21.6623 | True |
| G | I | 19.9172 | 0.001 | 14.1222 | 25.7122 | True |
| G | J | 23.7674 | 0.001 | 16.7526 | 30.7823 | True |
| G | K | 35.6874 | 0.001 | 27.6358 | 43.739 | True |
| G | L | 41.673 | 0.001 | 32.6129 | 50.7332 | True |
| G | M | 37.4242 | 0.001 | 28.3127 | 46.5357 | True |
| G | N | 46.6056 | 0.001 | 38.6734 | 54.5379 | True |
| G | O | 47.8545 | 0.001 | 39.4409 | 56.2681 | True |
| G | P | 64.1577 | 0.001 | 55.1521 | 73.1633 | True |
| G | Q | 67.8927 | 0.001 | 59.6528 | 76.1327 | True |
| H | I | 3.5464 | 0.8555 | -2.7228 | 9.8156 | False |
| H | J | 7.3966 | 0.0511 | -0.0148 | 14.8081 | False |
| H | K | 19.3166 | 0.001 | 10.9172 | 27.716 | True |
| H | L | 25.3022 | 0.001 | 15.9317 | 34.6728 | True |
| H | M | 21.0534 | 0.001 | 11.6332 | 30.4736 | True |
| H | N | 30.2348 | 0.001 | 21.9498 | 38.5199 | True |
| H | O | 31.4837 | 0.001 | 22.7367 | 40.2307 | True |
| H | P | 47.7869 | 0.001 | 38.469 | 57.1048 | True |
| H | Q | 51.5219 | 0.001 | 42.9418 | 60.102 | True |
| I | J | 3.8502 | 0.9 | -3.9287 | 11.6291 | False |
| I | K | 15.7702 | 0.001 | 7.0449 | 24.4956 | True |
| I | L | 21.7558 | 0.001 | 12.092 | 31.4196 | True |
| I | M | 17.507 | 0.001 | 7.795 | 27.219 | True |
| I | N | 26.6884 | 0.001 | 18.0731 | 35.3037 | True |
| I | O | 27.9373 | 0.001 | 18.8768 | 36.9977 | True |
| I | P | 44.2405 | 0.001 | 34.6278 | 53.8532 | True |
| I | Q | 47.9755 | 0.001 | 39.0761 | 56.8749 | True |
| J | K | 11.92 | 0.002 | 2.341 | 21.4991 | True |
| J | L | 17.9056 | 0.001 | 7.4646 | 28.3467 | True |
| J | M | 13.6568 | 0.001 | 3.1712 | 24.1424 | True |
| J | N | 22.8382 | 0.001 | 13.3593 | 32.3171 | True |
| J | O | 24.0871 | 0.001 | 14.2018 | 33.9723 | True |
| J | P | 40.3903 | 0.001 | 29.9965 | 50.7841 | True |
| J | Q | 44.1253 | 0.001 | 34.3875 | 53.8632 | True |
| K | L | 5.9856 | 0.9 | -5.1784 | 17.1496 | False |
| K | M | 1.7368 | 0.9 | -9.469 | 12.9425 | False |
| K | N | 10.9182 | 0.024 | 0.6483 | 21.1881 | True |
| K | O | 12.1671 | 0.0086 | 1.521 | 22.8131 | True |
| K | P | 28.4703 | 0.001 | 17.3504 | 39.5901 | True |
| K | Q | 32.2053 | 0.001 | 21.696 | 42.7146 | True |
| L | M | -4.2488 | 0.9 | -16.1998 | 7.7022 | False |
| L | N | 4.9326 | 0.9 | -6.1456 | 16.0108 | False |
| L | O | 6.1815 | 0.9 | -5.2464 | 17.6093 | False |
| L | P | 22.4847 | 0.001 | 10.6142 | 34.3552 | True |
| L | Q | 26.2197 | 0.001 | 14.9191 | 37.5203 | True |
| M | N | 9.1814 | 0.2582 | -1.9389 | 20.3017 | False |
| M | O | 10.4303 | 0.1257 | -1.0383 | 21.8989 | False |
| M | P | 26.7335 | 0.001 | 14.8238 | 38.6433 | True |
| M | Q | 30.4685 | 0.001 | 19.1267 | 41.8104 | True |
| N | O | 1.2489 | 0.9 | -9.3072 | 11.8049 | False |
| N | P | 17.5521 | 0.001 | 6.5184 | 28.5858 | True |
| N | Q | 21.2871 | 0.001 | 10.8689 | 31.7053 | True |
| O | P | 16.3032 | 0.001 | 4.9185 | 27.6879 | True |
| O | Q | 20.0382 | 0.001 | 9.249 | 30.8274 | True |
| P | Q | 3.735 | 0.9 | -7.5219 | 14.992 | False |
Em alguns casos não há diferença sifnigicativa na nota de ciências humanas. São as rendas: F e G, H e I, H e J, I e J, K e L, K e M, L e M, L e N, L e O, M e N, M e O, N e O, P e Q. Ao passo que as categorias vão aumentando, maior será a combinação entre elas. De fato, são muitas rendas que, se comparadas entre si, possuem uma diferença significativa. Entretanto, as aqui listadas não possuem nenhuma diferença significativa se comparadas entre si.
distrib_renda = pd.DataFrame(dados_renda['Q006_RESPOSTA'].value_counts(normalize = True)*100)
distrib_renda.columns = ['Proporção (%)']
distrib_renda.head()
| Proporção (%) | |
|---|---|
| De R 1.497,00. | 25.588004 |
| Até R$ 998,00. | 24.956822 |
| De R 1.996,00. | 9.856335 |
| De R 2.495,00. | 9.313079 |
| De R 3.992,00. | 5.909091 |
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
sns.barplot(x=distrib_renda['Proporção (%)'], y = distrib_renda.index, data=distrib_renda).set_title('Distribuição de candidatos pela renda ENEM 2019', fontsize = 16);
Metade dos candidatos do ENEM2019 tinham renda familiar de até 1497 reais. Há de se esperar que as rendas não estariam normalmente distribuídas. Um vídeo que elucida bem essa situação é o O segredo da MERITOCRACIA (clique aqui para visualizar o vídeo) do Átila Iamarino (biólogo e pesquisador).
Apesar do desempenho melhorar conforme a renda cresce, a maioria dos candidatos possuem renda precária. Esse é um reflexo histórico, político e econômico do país brasileiro que: passou por crises econômicas, sofreu golpe militar, foi explorado e escravizado (gerando um preconceiro estrutural), entre outros, os quais refletem, intrinsecamente, nas questões sociais e educacionais do próprio país.
Tanto como há uma má distribuição de renda, o Brasil NÃO se dispõem de um ensino educacional público de qualidade, onde se encontram as pessoas de menor renda.
Adendo
Constatação da hipótese anterior: candidatos da renda sugerida ('De 8.982,01 até 9.980,00 reais') são os menos representados pelos candidatos.
Para constar se o aluno é treineiro ou não, basta encontrar a variável que indica por "IN_TREINEIRO" como verdadeiro, ou seja, em booleano igual a 1.
treineiros_enem2019 = dados_enem2019.query('IN_TREINEIRO == 1') #Utilizando o query para buscar onde o dataset é igual a 1 em IN_TREINEIRO
treineiros_enem2019.head()
| NU_INSCRICAO | NU_ANO | CO_MUNICIPIO_RESIDENCIA | NO_MUNICIPIO_RESIDENCIA | CO_UF_RESIDENCIA | SG_UF_RESIDENCIA | NU_IDADE | TP_SEXO | TP_ESTADO_CIVIL | TP_COR_RACA | TP_NACIONALIDADE | CO_MUNICIPIO_NASCIMENTO | NO_MUNICIPIO_NASCIMENTO | CO_UF_NASCIMENTO | SG_UF_NASCIMENTO | TP_ST_CONCLUSAO | TP_ANO_CONCLUIU | TP_ESCOLA | TP_ENSINO | IN_TREINEIRO | CO_ESCOLA | CO_MUNICIPIO_ESC | NO_MUNICIPIO_ESC | CO_UF_ESC | SG_UF_ESC | TP_DEPENDENCIA_ADM_ESC | TP_LOCALIZACAO_ESC | TP_SIT_FUNC_ESC | IN_BAIXA_VISAO | IN_CEGUEIRA | IN_SURDEZ | IN_DEFICIENCIA_AUDITIVA | IN_SURDO_CEGUEIRA | IN_DEFICIENCIA_FISICA | IN_DEFICIENCIA_MENTAL | IN_DEFICIT_ATENCAO | IN_DISLEXIA | IN_DISCALCULIA | IN_AUTISMO | IN_VISAO_MONOCULAR | ... | TX_RESPOSTAS_CH | TX_RESPOSTAS_LC | TX_RESPOSTAS_MT | TP_LINGUA | TX_GABARITO_CN | TX_GABARITO_CH | TX_GABARITO_LC | TX_GABARITO_MT | TP_STATUS_REDACAO | NU_NOTA_COMP1 | NU_NOTA_COMP2 | NU_NOTA_COMP3 | NU_NOTA_COMP4 | NU_NOTA_COMP5 | NU_NOTA_REDACAO | Q001 | Q002 | Q003 | Q004 | Q005 | Q006 | Q007 | Q008 | Q009 | Q010 | Q011 | Q012 | Q013 | Q014 | Q015 | Q016 | Q017 | Q018 | Q019 | Q020 | Q021 | Q022 | Q023 | Q024 | Q025 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 190001004661 | 2019 | 1506138 | Redenção | 15 | PA | 17 | M | 1 | 3 | 1 | 1506138.0 | Redenção | 15.0 | PA | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | ACAEAAACABEBABAADCEEEDE*CBDCCCADADCCCBEBBBBDB | 99999CCCABBCAADDBCEBCCADBEEBDECBAABDEACACAEABB... | DEEDCAECDDEEECBCBECABEBAECBBCDAECAEBBBBBDCCDB | 1 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 60.0 | 100.0 | 80.0 | 80.0 | 100.0 | 420.0 | B | B | A | A | 4 | B | A | C | B | A | C | B | A | A | A | A | A | A | A | B | A | C | A | B | B |
| 4 | 190001004776 | 2019 | 1500800 | Ananindeua | 15 | PA | 16 | F | 1 | 3 | 1 | 1500800.0 | Ananindeua | 15.0 | PA | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | CCBCBEACABACABBBBACCBCEBDCBABCADADCBCADBAADEA | EBCAB99999BBCECBCACBEACBDAABDBCBBDACEBBACDCAEC... | AECCBBCBBCBDEDECACBAABEDABBEDDADCEADDBEBDBBEB | 0 | DEADBAAAEBEECEBCBCBCBDADAEABCEDDDDADCBEECACBC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | AADDDBEEEBEDDBEBACABCDBABECECACAECDCBDCCEDCDA | 1.0 | 160.0 | 140.0 | 160.0 | 160.0 | 160.0 | 780.0 | E | E | B | D | 3 | E | A | B | C | B | A | B | A | A | A | A | A | A | B | A | A | D | A | A | B |
| 12 | 190001005076 | 2019 | 1506138 | Redenção | 15 | PA | 15 | M | 1 | 3 | 1 | 1506138.0 | Redenção | 15.0 | PA | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | AADCCEDCCDBEABAECBABCEEACDEBDBBDBACBBEEDCADCB | AECBA99999ACDBECAACEAADBEAAAECDAECDEBAAEBCECEA... | DAADCAABECBBCBDADDEEEBCCAABADBBBECAACBDBDDCBC | 0 | BEEAAEBEEBADEADDADAEABCEDDDBCBCBCCACBCDADCCEB | EEBCEEDBADBBCBABCCADCEBACDBBACCACACBEADBBADCB | ADBBEDCABAABBCBCDAAECDDDBAAAECADECDCEBDEEAECBD... | BEDEEEAADBEBACABCDBABECECACADCBDCCEDCDABECDDD | 1.0 | 120.0 | 180.0 | 120.0 | 140.0 | 160.0 | 720.0 | C | E | D | D | 4 | F | A | C | C | B | B | B | B | A | A | B | A | A | B | B | A | C | A | A | B |
| 14 | 190001005081 | 2019 | 1506807 | Santarém | 15 | PA | 17 | F | 1 | 3 | 2 | NaN | NaN | NaN | NaN | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | AABCDEBCEBCADAAAAEEEBCEEBDECDBACBEDEAABAACDBA | 99999ADABAADAEABBAACDAABCDE*DABBABDAAEDAAAACBE... | AAAEDBCCEACBDDCBEAEBBCAAAABCCBABDCAAECCABCBDE | 1 | AAECACDEADCBCDDDBCBDADAEABCEBABEEBCBEECEBDADC | ACACEEBCCBABADBBBACDBBACCCCADCEBADCBEEDBBEADB | EBBADCABDABACBCEBDEEAAADDBECDECDDBADBCDAAECBCC... | EEEADBEBACABCDBABECECACDCBDCCEDCDABEDECDDDBAA | 1.0 | 120.0 | 80.0 | 60.0 | 120.0 | 20.0 | 400.0 | D | E | F | F | 4 | B | A | B | C | A | A | B | A | B | A | A | A | A | B | A | A | D | A | A | B |
| 16 | 190001005202 | 2019 | 1502301 | Capitão Poço | 15 | PA | 17 | F | 1 | 3 | 2 | NaN | NaN | NaN | NaN | 3 | 0 | 1 | NaN | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | EEEAABAADADCBCEDBCCACEEDBCBCBADBBAABDBBABCEAB | 99999ECABECCBABCDAEADABEBEEBEEEEEDBDDBAACDAEAA... | ACBEDECCABCEDDEDCEDAACBCAADEEDCDEECBABEBAEC*B | 1 | AAECACDEADCBCDDDBCBDADAEABCEBABEEBCBEECEBDADC | BACCCBABBADCBCEEEBCACACEEDBCCADBEADBADBBBACDB | BDABEABCADBCBAADDBECDAAECDAECBECBCCDEEAAADDBBC... | EEEADBEBACABCDBABECECACDCBDCCEDCDABEDECDDDBAA | 1.0 | 120.0 | 120.0 | 120.0 | 120.0 | 100.0 | 580.0 | D | E | B | B | 3 | B | A | B | C | A | A | B | B | A | A | B | A | A | B | B | A | C | A | A | A |
5 rows × 136 columns
estados_treineiros2019 = treineiros_enem2019['SG_UF_RESIDENCIA'] #Coletando os estados
serie_estados_t2019 = estados_treineiros2019.value_counts(normalize = True)*100 #Referenciando a proporção para cada um
lista_estados_treineiros = pd.DataFrame(data = serie_estados_t2019) #Criando um dataframe com os dados
lista_estados_treineiros.columns = ['Proporção (%)'] #Renomeando a coluna
#Plotando o gráfico com a escala da proporção
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
ax = sns.barplot(x=lista_estados_treineiros.index, y = lista_estados_treineiros['Proporção (%)'], data=lista_estados_treineiros).set_title('Participação de treineiros no ENEM-2019 por Estado', fontsize = 16)
Percebe-se que, a partir do gráfico de barras é visível a maior participação de treineiros nos Estados de São Paulo e Minas Gerais. É possível relacionar com a população de cada estado, como também relaiconar com a maior presença de mães com pós-graduação nos mesmos estados, aos quais instigam seus filhos à se aventurarem no enem. Vamos analisar por categorias.
tipo_sexo_treineiros = treineiros_enem2019['TP_SEXO'] #Coletando a Série
tipo_sexo_treineiros.value_counts(normalize = True)
F 0.62944 M 0.37056 Name: TP_SEXO, dtype: float64
Pode-se concluir que, 62,9% dos treineiros são compostos pelo sexo feminino visível no gráfico a seguir.
plt.figure(figsize=(5, 5))
tipo_sexo_treineiros.value_counts(normalize = True).plot.pie().set_title('Distribuição de Sexo nos candidatos Treineiros', fontsize = 16);
Concatenando as respostas
treineiros_enem2019['Q001_RESPOSTA_PAI'] = [respostas_escolaridade_pais[respostas] for respostas in treineiros_enem2019.Q001]
treineiros_enem2019['Q002_RESPOSTA_MAE'] = [respostas_escolaridade_pais[respostas] for respostas in treineiros_enem2019.Q002]
treineiros_enem2019[['Q002', 'Q002_RESPOSTA_MAE']].head()
| Q002 | Q002_RESPOSTA_MAE | |
|---|---|---|
| 0 | B | Não completou a 4ª série/5º ano do Ensino Fund... |
| 4 | E | Completou o Ensino Médio, mas não completou a ... |
| 12 | E | Completou o Ensino Médio, mas não completou a ... |
| 14 | E | Completou o Ensino Médio, mas não completou a ... |
| 16 | E | Completou o Ensino Médio, mas não completou a ... |
treineiros_pai = pd.DataFrame(treineiros_enem2019['Q001_RESPOSTA_PAI'].value_counts(normalize = True))
treineiros_pai.plot.barh().set_title('Proporção de escolaridade do pai para treineiros ENEM2019', fontsize = 16);
treineiros_mae = pd.DataFrame(treineiros_enem2019['Q002_RESPOSTA_MAE'].value_counts(normalize = True))
treineiros_mae.plot.barh().set_title('Proporção de escolaridade da mãe para treineiros ENEM2019', fontsize = 16);
Por geral, os candidatos treineiros são pouco influenciados por pais que nunca estudaram ou que são ausentes (Resposta igual a Não sei). Entretanto, quando mais desenvolvida a escolaridade dos pais, seja até o ensino médio completo, a influência dos pais é maior.
Concatenando as respostas
treineiros_enem2019['Q006_RESPOSTA'] = [rendas[resposta] for resposta in treineiros_enem2019.Q006]
treineiros_enem2019[['Q006', 'Q006_RESPOSTA']].head()
| Q006 | Q006_RESPOSTA | |
|---|---|---|
| 0 | B | Até R$ 998,00. |
| 4 | E | De R 2.495,00. |
| 12 | F | De R 2.994,00. |
| 14 | B | Até R$ 998,00. |
| 16 | B | Até R$ 998,00. |
treineiros_renda = pd.DataFrame(treineiros_enem2019['Q006_RESPOSTA'].value_counts(normalize = True))
treineiros_renda.plot.barh().set_title('Proporção de renda familiar para treineiros ENEM2019', fontsize = 16);
A maioria dos treineiros, possuem uma renda de até 998 reais seguido daqueles que estão entre 998 e 1497 reais. O enem disponibiliza a isenção de valor para candidatos com rendas inferiores, que estudam em escolas públicas ou que participam do Cadastro único para Programas Sociais do Governo Federal. O reflexo dessa política pode estar no incentivo desses treineiros com rendas mais precárias
A maioria das análises compostas por aqui dispõem de resultados que demonstram as regiões Sul e Sudeste como as que obtiveram os melhores desempenhos. Agora, qual o motivo desses acontecimentos?
A priori, observe o mapa a seguir:

Observe o mapa acima para identificar as regiões brasileiras. Irei me referenciar sobre as regiões em amarelo e azul, ou seja, sudeste e sul do Brasil.
Separando os dados das regiões Sul e Sudeste
rs = dados_enem2019.loc[dados_enem2019['SG_UF_RESIDENCIA'] == 'RS']
sc = dados_enem2019.loc[dados_enem2019['SG_UF_RESIDENCIA'] == 'SC']
pr = dados_enem2019.loc[dados_enem2019['SG_UF_RESIDENCIA'] == 'PR']
sp = dados_enem2019.loc[dados_enem2019['SG_UF_RESIDENCIA'] == 'SP']
rj = dados_enem2019.loc[dados_enem2019['SG_UF_RESIDENCIA'] == 'RJ']
mg = dados_enem2019.loc[dados_enem2019['SG_UF_RESIDENCIA'] == 'MG']
es = dados_enem2019.loc[dados_enem2019['SG_UF_RESIDENCIA'] == 'ES']
dados_enem2019_sul_sudeste = pd.concat([rs,sc,pr,sp,rj,mg,es], axis=0)
dados_enem2019_sul_sudeste['SG_UF_RESIDENCIA'].value_counts()
SP 20264 MG 13547 RJ 8467 RS 5466 PR 5259 SC 2673 ES 2550 Name: SG_UF_RESIDENCIA, dtype: int64
Como visto nos relatórios de análises distruídas por todo esse projeto, é nítido que há diferenças significativas entre questões sociais sobre os candidatos que, intrinsecamente, inferem sobre suas notas e seu desempenho no ENEM. Cabe, então, analisar se essas mesmas estão interferindo a região Sul e Sudeste do país.
As diferentes cores de raças interferem de forma astronômica nas notas dos candidatos do ENEM 2019. A partir dos testes realizados aqui, foi possível concluir que há uma diferença significativa entre elas. Em todos os boxplots, a cor que se demonstrou disparada foi a Branca. Os motivos foram desenvolvidos e parcialmente explicados nas seções sobre as raças. É nítida a desigualdade social.
Diante disso, como as cores das raças estão distribuídas no sul e no sudeste?
dados_enem2019_sul_sudeste['TP_COR_RACA_RESPOSTA'] = [cor_raca[i] for i in dados_enem2019_sul_sudeste.TP_COR_RACA]
racas_enem_atual_sul_sudeste = pd.DataFrame(dados_enem2019_sul_sudeste['TP_COR_RACA_RESPOSTA'].value_counts())
#Plotando o gráfico com a escala da proporção
plt.figure(figsize=(10, 8))
sns.set_theme(style="whitegrid")
ax = sns.barplot(x=racas_enem_atual_sul_sudeste.index, y = racas_enem_atual_sul_sudeste['TP_COR_RACA_RESPOSTA'], data=racas_enem_atual_sul_sudeste, order = racas_ordenadas).set_title('Distribuição candidatos do Sul e do Sudeste no ENEM 2019 por Raça', fontsize = 16)
racas_enem_atual_sul_sudeste = pd.DataFrame(dados_enem2019_sul_sudeste['TP_COR_RACA_RESPOSTA'].value_counts(normalize = True))
racas_enem_atual_sul_sudeste
| TP_COR_RACA_RESPOSTA | |
|---|---|
| Branca | 0.522189 |
| Parda | 0.321626 |
| Preta | 0.114244 |
| Amarela | 0.020060 |
| Não declarado | 0.018411 |
| Indígena | 0.003469 |
Captamos um possível fator capaz de explicar o porquê do desempenho dessa região. A maioria dos candidatos eram Brancos que, por "consequência", tiveram um desempenho melhor.
Ficou nítido o efeito que a renda familiar tem sob as notas do enem dos candidatos. Quanto maior a renda, maiores serão as notas dos candidatos. De fato, localizar onde as rendas tem seu maior nível pode ajudar a identificar mais um ponto sob a hipótese aqui deixada.
concatenado_renda.plot.scatter(y='latitude', x = 'longitude',
c = concatenado_renda['Mean'],
cmap = 'YlGnBu',
figsize = (8,8)).set_title('Distribuição de renda familiar dos candidatos ENEM 2019 por Município', fontsize = 16);
De acordo com o mapa deixado no início dessa seção, é possível visualizar com nitidez onde há uma maior renda familiar. A região em azul (onde o nuance tende ao Sul do País) reflete exatamente os pontos onde as regiões propostas se desempenharam melhor. Outro ponto a ser levado como argumento.
Ter acesso à internet tem um efeito positivo nas notas dos candidatos, onde as mesmas se elevam significamente. O mundo globalizado possibilita o acesso à informação de forma fácil e rápida, principalmente pelo atributo dessa parte: a internet. Garantir esse "corta caminho" de não precisar, necessariamente, de livros físicos, e sim ter a disponibilidade deles digitalmente, como também obter todo o suporte de portais educacionais e de estudos disponíveis na internet, leva o candidato a ter um desempenho melhor.
Avaliar a proporção de candidatos que tinham acesso a internet nessa região, ajuda a ressaltar mais um argumento.
dados_enem2019_sul_sudeste['Q025_RESPOSTA'] = [acesso_internet[resposta] for resposta in dados_enem2019_sul_sudeste.Q025]
tinham_acesso_internet_sul_sudeste = pd.DataFrame(dados_enem2019_sul_sudeste['Q025_RESPOSTA'].value_counts())
tinham_acesso_internet_sul_sudeste.plot.barh().set_title('O candidato tem acesso a internet? ENEM2019 (Sul, Sudeste)', fontsize = 16);
tinham_acesso_internet_sul_sudeste = pd.DataFrame(dados_enem2019_sul_sudeste['Q025_RESPOSTA'].value_counts(normalize =True))
tinham_acesso_internet_sul_sudeste
| Q025_RESPOSTA | |
|---|---|
| Sim | 0.875657 |
| Não | 0.124343 |
A maioria esmagadora dos candidatos que viviam no Sul ou no Sudeste tinham acesso à internet. Outro ponto explicativo do porquê.
Os candidatos que escolheram o inglês como língua estrangeira se desempenharam relativamente melhor daqueles que escolheram o espanhol. Os motivos pelos quais eu suponho são desenvolvidos na própria seção sobre esse tema. Quantos candidatos escolheram o inglês nessa região?
lingua = {
0: 'Inglês',
1: 'Espanhol'
}
dados_enem2019_sul_sudeste['LINGUA_ESTRANGEIRA'] = [lingua[resposta] for resposta in dados_enem2019_sul_sudeste.TP_LINGUA]
lingua_estrangeira_sul_sudeste = pd.DataFrame(dados_enem2019_sul_sudeste['LINGUA_ESTRANGEIRA'].value_counts())
lingua_estrangeira_sul_sudeste.plot.barh().set_title('Distribuição para escolha da língua estrangeira ENEM2019 (Sul, Sudeste)', fontsize = 16);
lingua_estrangeira_sul_sudeste = pd.DataFrame(dados_enem2019_sul_sudeste['LINGUA_ESTRANGEIRA'].value_counts(normalize =True))
lingua_estrangeira_sul_sudeste
| LINGUA_ESTRANGEIRA | |
|---|---|
| Inglês | 0.588414 |
| Espanhol | 0.411586 |
Apesar de aproximadamente dois quintos escolherem espanhol, três quintos escolheram o inglês como língua estrangeira no Sul ou no Sudeste. Mais um ponto a argumentar pelo desempenho.
Na seção onde avalio se há relação entre o IDH Municipal e o desempenho do aluno, é possível visualizar que há uma leve tendência de correlação entre as variáveis. Vamos observar como que o Índice de Desenvolvimento Humano está distribuído no País de acordo com os Estados.
Definindo a função para baixar arquivos
def baixar_arquivo(url, endereco=None):
if endereco is None:
endereco = os.path.basename(url.split("?")[0])
resposta = requests.get(url, stream=True)
if resposta.status_code == requests.codes.OK:
with open(endereco, 'wb') as novo_arquivo:
for parte in resposta.iter_content(chunk_size=256):
novo_arquivo.write(parte)
print("Download finalizado. Arquivo salvo em: {}".format(endereco))
else:
resposta.raise_for_status()
Gerando o mapa de IDH por Estado (Aguarde o mapa aparecer e mexa com o scroll do mouse)
estados_br = 'https://raw.githubusercontent.com/sandeco/CanalSandeco/master/covid-19/br_states.json'
baixar_arquivo(estados_br)
idh_estados = pd.read_csv('https://raw.githubusercontent.com/mathllorente/idh/main/mapa.csv')
idh_estados['ID'] = ['RO', 'PA', 'AM', 'RR', 'TO', 'AC', 'AP', 'PI', 'MA', 'CE', 'PE', 'AL', 'SE', 'PB', 'BA', 'MG', 'ES', 'RN', 'SP', 'SC', 'RJ', 'PR', 'RS', 'MS', 'MT', 'GO', 'DF']
idh_estados.columns = ['Local', 'IDH', 'ID']
geo_json_data = json.load(open('br_states.json'))
mapa = folium.Map(
width=800, height=800,
location=[-15.77972, -47.92972],
zoom_start=4
)
mapa.choropleth(
geo_data = geo_json_data,
name = 'IDH',
data = idh_estados,
columns = ['ID', 'IDH'],
key_on = 'feature.id',
fill_color = 'Blues',
fill_opacity = 0.8,
line_color = 'white',
line_opacity = 0.8,
show = True,
legend_name = 'IDH por Estado'
)
mapa
É nítido que as regiões Sul e Sudeste são as que concentram um IDH maior que o resto do País. Outro ponto a ser considerado como argumento.
Avaliar pela maioria também pode ser um fator a ser levantado. Irei visualizar quantos candidatos eram dessa região.
print('{}% dos candidatos do ENEM 2019 residiam na região Sudeste ou Sul do Brasil.'.format(round((len(dados_enem2019_sul_sudeste)/len(dados_enem2019)*100), 2)))
45.71% dos candidatos do ENEM 2019 residiam na região Sudeste ou Sul do Brasil.
O movimento feminista, como desenvolido na hipótese da seção sobre a desigualdade de sexo entre os candidatos, pode ajudar no desempenho das mulheres na prova de linguagens. Essa área ocupa um comportamento linguístico social, onde o mesmo movimento de luta pela igualdade de gênero tem força. Sua força tem avançado por todo o país, possibilitando um melhor desempenho nessas questões sociais. Essas forças realizam manifestações em polos, populacionais aos quais o Sul e o Sudeste têm forças. Um ponto a ser levado em consideração.
De fato, quanto mais desenvolvida a escolaridade dos pais, melhor será o desempenho de seus filhos. Esse argumento foi desenvolvido na seção "Como que a escolaridade dos pais influencia nas notas?". Analisar como estão distribuídas as maiores notas pela escolaridade dos pais é um meio útil de se avaliar essa região.
Dentre as maiores notas, quais foram as escolaridades dos pais dos candidatos que tiveram maior relevância? Essas escolaridades estão distribuídas como pelo país?
Mães
notas_maiores_mae_atual.plot.barh().set_title('Escolaridade das Mães dos candidatos com notas maiores que 600 ENEM 2019', fontsize = 16);
O quanto o Sul e o Sudeste representam das maiores categorias?
mae_com_pos_sul_sudeste = influencia_pais.loc[influencia_pais['Q002_RESPOSTA_MAE'] == 'Completou a Pós-graduação.']
estado_mae_com_pos_sul_sudeste = mae_com_pos_sul_sudeste['SG_UF_RESIDENCIA'].value_counts(normalize =True)*100
print('{}% das mães dos candidatos do ENEM 2019 que tinham escolaridade até a Pós-graduação eram do Sul ou do Sudeste.'.format(round(estado_mae_com_pos_sul_sudeste[['SP', 'MG', 'RJ', 'ES', 'PR', 'RS', 'SC']].sum(), 2)))
52.8% das mães dos candidatos do ENEM 2019 que tinham escolaridade até a Pós-graduação eram do Sul ou do Sudeste.
mae_com_faculdade_sul_sudeste = influencia_pais.loc[influencia_pais['Q002_RESPOSTA_MAE'] == 'Completou a Faculdade, mas não completou a Pós-graduação.']
estado_mae_com_faculdade_sul_sudeste = mae_com_faculdade_sul_sudeste['SG_UF_RESIDENCIA'].value_counts(normalize =True)*100
print('{}% das mães dos candidatos do ENEM 2019 que tinham escolaridade até a Faculdade completa eram do Sul ou do Sudeste.'.format(round(estado_mae_com_faculdade_sul_sudeste[['SP', 'MG', 'RJ', 'ES', 'PR', 'RS', 'SC']].sum(), 2)))
53.32% das mães dos candidatos do ENEM 2019 que tinham escolaridade até a Faculdade completa eram do Sul ou do Sudeste.
mae_com_em_sul_sudeste = influencia_pais.loc[influencia_pais['Q002_RESPOSTA_MAE'] == 'Completou o Ensino Médio, mas não completou a Faculdade.']
estado_mae_com_em_sul_sudeste = mae_com_em_sul_sudeste['SG_UF_RESIDENCIA'].value_counts(normalize =True)*100
print('{}% das mães dos candidatos do ENEM 2019 que tinham escolaridade até o Ensino Médio Completo eram do Sul ou do Sudeste.'.format(round(estado_mae_com_em_sul_sudeste[['SP', 'MG', 'RJ', 'ES', 'PR', 'RS', 'SC']].sum(), 2)))
47.47% das mães dos candidatos do ENEM 2019 que tinham escolaridade até o Ensino Médio Completo eram do Sul ou do Sudeste.
Pais
notas_maiores_pai_atual.plot.barh().set_title('Escolaridade dos Pais dos candidatos com notas maiores que 600 ENEM 2019', fontsize = 16);
O quanto o Sul e o Sudeste representam das maiores categorias?
pai_com_pos_sul_sudeste = influencia_pais.loc[influencia_pais['Q001_RESPOSTA_PAI'] == 'Completou a Pós-graduação.']
estado_pai_com_pos_sul_sudeste = pai_com_pos_sul_sudeste['SG_UF_RESIDENCIA'].value_counts(normalize =True)*100
print('{}% dos pais dos candidatos do ENEM 2019 que tinham escolaridade até a Pós-graduação eram do Sul ou do Sudeste.'.format(round(estado_pai_com_pos_sul_sudeste[['SP', 'MG', 'RJ', 'ES', 'PR', 'RS', 'SC']].sum(), 2)))
58.59% dos pais dos candidatos do ENEM 2019 que tinham escolaridade até a Pós-graduação eram do Sul ou do Sudeste.
pai_com_faculdade_sul_sudeste = influencia_pais.loc[influencia_pais['Q001_RESPOSTA_PAI'] == 'Completou a Faculdade, mas não completou a Pós-graduação.']
estado_pai_com_faculdade_sul_sudeste = pai_com_faculdade_sul_sudeste['SG_UF_RESIDENCIA'].value_counts(normalize =True)*100
print('{}% dos pais dos candidatos do ENEM 2019 que tinham escolaridade até a Faculdade completa eram do Sul ou do Sudeste.'.format(round(estado_pai_com_faculdade_sul_sudeste[['SP', 'MG', 'RJ', 'ES', 'PR', 'RS', 'SC']].sum(), 2)))
58.3% dos pais dos candidatos do ENEM 2019 que tinham escolaridade até a Faculdade completa eram do Sul ou do Sudeste.
pai_com_em_sul_sudeste = influencia_pais.loc[influencia_pais['Q001_RESPOSTA_PAI'] == 'Completou o Ensino Médio, mas não completou a Faculdade.']
estado_pai_com_em_sul_sudeste = pai_com_em_sul_sudeste['SG_UF_RESIDENCIA'].value_counts(normalize =True)*100
print('{}% dos pais dos candidatos do ENEM 2019 que tinham escolaridade até o Ensino Médio Completo eram do Sul ou do Sudeste.'.format(round(estado_pai_com_em_sul_sudeste[['SP', 'MG', 'RJ', 'ES', 'PR', 'RS', 'SC']].sum(), 2)))
51.07% dos pais dos candidatos do ENEM 2019 que tinham escolaridade até o Ensino Médio Completo eram do Sul ou do Sudeste.
Mais da metade, na maioria dos casos, as mães e os pais se locaizam na região Sul/Sudeste. Outro argumento a ser considerado como resposta.
Para rodar os códigos, é necessária a instalação dos seguintes pacotes
ATENÇÃO: Possivelmente será necessária a reconexão com o colab para que os pacotes sejam rodados corretamente

!pip install pycaret
!pip install shap
Bibliotecas
import os
import requests
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
import folium
from folium import plugins
import json
import statsmodels.api as sm
from statsmodels.formula.api import ols
from statsmodels.stats.multicomp import MultiComparison
from sklearn.model_selection import train_test_split
#Coletando a fonte dos dados
font = "https://github.com/alura-cursos/imersao-dados-2-2020/blob/master/MICRODADOS_ENEM_2019_SAMPLE_43278.csv?raw=true"
#Utilizando o pandas para ler o arquivo csv
dados_enem2019 = pd.read_csv(font)
#Visualizando as 5 primeiras linhas dos dados carregados
dados_enem2019.head()
PyCaret é uma biblioteca que possibilita o automachinelearning (AutoML), de código aberto, onde para desenvolver um modelo de aprendizagem de máquinas são necessárias poucas linhas de código. Sua capacidade é astronômica!
A documentação pode ser encontrada aqui: https://pycaret.org/
Para realizar as predições, estarei utilizando modelos de Regressão, pelo fato de: irei utilizar as notas nas outras áreas, que assumem um valor numérico para prever um valor numérico. n
from pycaret.regression import *
import pycaret
from pycaret.utils import enable_colab
Como dito anteriormente, estarei separando apenas as notas, estarei eliminando os Missing Values para tornar o modelo mais coerente e saudável e também estarei analisando a correlação entre essas variáveis.
dados_machine_learning = dados_enem2019[['NU_NOTA_MT', 'NU_NOTA_CH', 'NU_NOTA_LC', 'NU_NOTA_CN']]
dados_machine_learning = dados_machine_learning.dropna()
correlacao = dados_machine_learning.corr()
correlacao
| NU_NOTA_MT | NU_NOTA_CH | NU_NOTA_LC | NU_NOTA_CN | |
|---|---|---|---|---|
| NU_NOTA_MT | 1.000000 | 0.610570 | 0.587986 | 0.650386 |
| NU_NOTA_CH | 0.610570 | 1.000000 | 0.748561 | 0.669259 |
| NU_NOTA_LC | 0.587986 | 0.748561 | 1.000000 | 0.641998 |
| NU_NOTA_CN | 0.650386 | 0.669259 | 0.641998 | 1.000000 |
Plotando um gráfico para analisar a correlação de pearson
sns.heatmap(correlacao, cmap="Blues", center=0, annot=True);
De fato, visivelmente a nota de Linguagens e Códigos é a que mais influencia a nota de Ciências Humanas. Qual é o comportamento dessas variáveis em um modelo de machine learning para prever a nota de Ciências Humanas?
Visualizando os dados
dados_machine_learning.head()
| NU_NOTA_MT | NU_NOTA_CH | NU_NOTA_LC | NU_NOTA_CN | |
|---|---|---|---|---|
| 0 | 432.4 | 512.3 | 488.6 | 435.6 |
| 2 | 427.2 | 499.1 | 441.0 | 423.2 |
| 3 | 499.9 | 578.1 | 551.5 | 426.2 |
| 4 | 424.5 | 571.3 | 511.2 | 516.5 |
| 5 | 615.6 | 618.7 | 607.5 | 559.6 |


train, validation = train_test_split(dados_machine_learning, test_size=0.2,
random_state=1234)
reg = setup(data = train,
target = 'NU_NOTA_CH', train_size = 0.7, session_id = 1234)
Setup Succesfully Completed.
| Description | Value | |
|---|---|---|
| 0 | session_id | 1234 |
| 1 | Transform Target | False |
| 2 | Transform Target Method | None |
| 3 | Original Data | (74031, 4) |
| 4 | Missing Values | False |
| 5 | Numeric Features | 3 |
| 6 | Categorical Features | 0 |
| 7 | Ordinal Features | False |
| 8 | High Cardinality Features | False |
| 9 | High Cardinality Method | None |
| 10 | Sampled Data | (22209, 4) |
| 11 | Transformed Train Set | (15546, 3) |
| 12 | Transformed Test Set | (6663, 3) |
| 13 | Numeric Imputer | mean |
| 14 | Categorical Imputer | constant |
| 15 | Normalize | False |
| 16 | Normalize Method | None |
| 17 | Transformation | False |
| 18 | Transformation Method | None |
| 19 | PCA | False |
| 20 | PCA Method | None |
| 21 | PCA Components | None |
| 22 | Ignore Low Variance | False |
| 23 | Combine Rare Levels | False |
| 24 | Rare Level Threshold | None |
| 25 | Numeric Binning | False |
| 26 | Remove Outliers | False |
| 27 | Outliers Threshold | None |
| 28 | Remove Multicollinearity | False |
| 29 | Multicollinearity Threshold | None |
| 30 | Clustering | False |
| 31 | Clustering Iteration | None |
| 32 | Polynomial Features | False |
| 33 | Polynomial Degree | None |
| 34 | Trignometry Features | False |
| 35 | Polynomial Threshold | None |
| 36 | Group Features | False |
| 37 | Feature Selection | False |
| 38 | Features Selection Threshold | None |
| 39 | Feature Interaction | False |
| 40 | Feature Ratio | False |
| 41 | Interaction Threshold | None |
Execute a célula abaixo e aguarde o processo ser finalizado.
A declaração fold = 10 significa que as métricas estão sendo baseadas em dez camadas de cross-validation.

Fonte: https://ethen8181.github.io/machine-learning/model_selection/model_selection.html
O objetivo da validação cruzada é testar a capacidade do modelo de prever novos dados que não foram usados para estimá-los, a fim de sinalizar problemas como o excesso de adequação ou viés de seleção e dar uma visão de como o modelo se generalizará para um conjunto de dados independente (ou seja, um conjunto de dados desconhecido, por exemplo, a partir de um problema real). Referência: https://en.wikipedia.org/wiki/Cross-validation_(statistics)
# Treinar modelos
compare_models(fold = 10)
| Model | MAE | MSE | RMSE | R2 | RMSLE | MAPE | TT (Sec) | |
|---|---|---|---|---|---|---|---|---|
| 0 | Extreme Gradient Boosting | 36.8409 | 2294.2634 | 47.8899 | 0.6484 | 0.1707 | 0.0765 | 0.4811 |
| 1 | Gradient Boosting Regressor | 36.8326 | 2294.6315 | 47.8932 | 0.6483 | 0.1720 | 0.0765 | 1.4258 |
| 2 | Lasso Regression | 37.3785 | 2382.4312 | 48.8026 | 0.6350 | 0.1962 | 0.0777 | 0.0085 |
| 3 | Bayesian Ridge | 37.3784 | 2382.4310 | 48.8026 | 0.6350 | 0.1962 | 0.0777 | 0.0073 |
| 4 | Linear Regression | 37.3780 | 2382.4311 | 48.8026 | 0.6350 | 0.1962 | 0.0777 | 0.0054 |
| 5 | Elastic Net | 37.3784 | 2382.4310 | 48.8026 | 0.6350 | 0.1962 | 0.0777 | 0.0071 |
| 6 | Ridge Regression | 37.3780 | 2382.4311 | 48.8026 | 0.6350 | 0.1962 | 0.0777 | 0.0057 |
| 7 | Least Angle Regression | 37.3780 | 2382.4311 | 48.8026 | 0.6350 | 0.1962 | 0.0777 | 0.0059 |
| 8 | Huber Regressor | 37.2226 | 2393.5519 | 48.9168 | 0.6333 | 0.1967 | 0.0780 | 0.0986 |
| 9 | Random Sample Consensus | 37.1964 | 2404.3923 | 49.0274 | 0.6317 | 0.1951 | 0.0780 | 0.2658 |
| 10 | TheilSen Regressor | 37.3803 | 2407.0239 | 49.0544 | 0.6312 | 0.1948 | 0.0781 | 3.6377 |
| 11 | Light Gradient Boosting Machine | 37.3499 | 2421.8964 | 49.2062 | 0.6291 | 0.2076 | 0.0772 | 0.1193 |
| 12 | CatBoost Regressor | 37.3816 | 2447.8509 | 49.4682 | 0.6252 | 0.2087 | 0.0773 | 3.6928 |
| 13 | Support Vector Machine | 37.2162 | 2507.9217 | 50.0626 | 0.6161 | 0.2124 | 0.0774 | 11.5869 |
| 14 | Random Forest | 38.8620 | 2541.6556 | 50.4047 | 0.6105 | 0.1610 | 0.0805 | 3.6190 |
| 15 | Extra Trees Regressor | 39.6427 | 2652.1287 | 51.4890 | 0.5935 | 0.1730 | 0.0821 | 1.5707 |
| 16 | K Neighbors Regressor | 40.4512 | 2748.8326 | 52.4185 | 0.5787 | 0.1632 | 0.0838 | 0.0117 |
| 17 | Orthogonal Matching Pursuit | 41.2409 | 2870.6106 | 53.5700 | 0.5605 | 0.1764 | 0.0856 | 0.0061 |
| 18 | AdaBoost Regressor | 48.1666 | 3873.5809 | 61.6467 | 0.4044 | 0.2220 | 0.0957 | 0.3552 |
| 19 | Decision Tree | 52.7425 | 4708.5100 | 68.5896 | 0.2788 | 0.2414 | 0.1087 | 0.0847 |
| 20 | Passive Aggressive Regressor | 56.5897 | 4819.7975 | 68.3252 | 0.2652 | 0.2180 | 0.1140 | 0.0139 |
| 21 | Lasso Least Angle Regression | 65.9151 | 6543.9544 | 80.8756 | -0.0007 | 0.2474 | 0.1344 | 0.0058 |
XGBRegressor(base_score=0.5, booster='gbtree', colsample_bylevel=1,
colsample_bynode=1, colsample_bytree=1, gamma=0,
importance_type='gain', learning_rate=0.1, max_delta_step=0,
max_depth=3, min_child_weight=1, missing=None, n_estimators=100,
n_jobs=-1, nthread=None, objective='reg:linear', random_state=1234,
reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None,
silent=None, subsample=1, verbosity=0)
As referências foram extraídas de um post no medium do Felipe Azank. Sigam ele clicando aqui: https://medium.com/@felipeazank
O post utilizado foi: https://medium.com/turing-talks/como-avaliar-seu-modelo-de-regress%C3%A3o-c2c8d73dab96
Como visto pela tabela acima, o modelo de Extreme Gradient Boosting gerou, pela maioria, os melhores resultados. Mas o que significa cada resultado?
MAE
O Erro Absoluto Médio (Mean Absolute Error) consiste na média das distâncias entre valores preditos e reais. Essa métrica não depende muito da variância dos dados.

MSE
Métrica mais utilizada, o Erro Quadrático Médio (Mean Squared Error) consiste na média do erro das previsões ao quadrado. Essa métrica é fortemente influenciada pela variância dos dados.

RMSE
Raiz do erro quadrático médio (RMSE), como o próprio nome diz, realiza a raiz quadrada da métrica anterior. Entretanto, essa medida, assim como o MSE, penaliza predições muito distantes da real.

R2
O valor do seu R-Quadrado varia de 0 a 1 e geralmente é representado em porcentagem. Um R² = 80% explica que 80% da variância de nossos dados podem ser explicados pelo modelo construído, enquanto os outros 20%, teoricamente, se tratariam de uma variância residual.

RMSLE Raiz do erro médio quadrático e logarítmico, essa métrica realiza um cálculo similar ao do RMSE.

MAPE Erro Percentual Absoluto Médio (MAPE), assume uma avaliação de, assim como o MSE e o MAE, quanto menor o valor, mais preciso seria o modelo de regressão. Obter um MAPE= 10% significa que, em média, nosso modelo faz previsões que erram por 10% do valor real.

Agora que cada métrica foi brevemente explicada, vamos observar o desempenho para cada uma delas nas 10 gerações e grupos de bateria de testes do modelo.
xgboost = create_model('xgboost')
| MAE | MSE | RMSE | R2 | RMSLE | MAPE | |
|---|---|---|---|---|---|---|
| 0 | 37.3429 | 2370.2550 | 48.6853 | 0.6582 | 0.1861 | 0.0784 |
| 1 | 35.8662 | 2255.9464 | 47.4968 | 0.6418 | 0.2239 | 0.0733 |
| 2 | 36.8818 | 2445.5489 | 49.4525 | 0.6398 | 0.2643 | 0.0753 |
| 3 | 36.9203 | 2296.4192 | 47.9210 | 0.6491 | 0.1914 | 0.0773 |
| 4 | 37.8342 | 2337.9064 | 48.3519 | 0.6247 | 0.1010 | 0.0783 |
| 5 | 37.0529 | 2241.2237 | 47.3416 | 0.6585 | 0.1306 | 0.0775 |
| 6 | 37.6555 | 2389.0553 | 48.8780 | 0.6033 | 0.1870 | 0.0780 |
| 7 | 36.6798 | 2177.7864 | 46.6668 | 0.6820 | 0.1300 | 0.0764 |
| 8 | 35.9119 | 2163.5903 | 46.5144 | 0.6787 | 0.1085 | 0.0756 |
| 9 | 36.2639 | 2264.9027 | 47.5910 | 0.6478 | 0.1845 | 0.0748 |
| Mean | 36.8409 | 2294.2634 | 47.8899 | 0.6484 | 0.1707 | 0.0765 |
| SD | 0.6424 | 86.8002 | 0.9054 | 0.0223 | 0.0497 | 0.0016 |
As métricas acima foram retiradas do conjunto de treino. É possível realizar um intervalo de confiança em 95% para limitar um possível intervalo de correspondência ao valor real.

Os nossos modelos estão distribuídos dispersos da média em questão. A partir da média é possível avaliar o desvio padrão. Em poucas palavras, essa métrica avalia o quão distantes os dados estão dispersos da média (ele é a raiz quadrada da variância).
No gráfico acima é possível visualizar que, o valor da média menos um desvio padrão até o valor da média mais um desvio padrão ocupa 68% dos nossos dados. Nosso objetivo é ocupar um intervalo de 95%.
O que significa isso? Podemos simplicar dizendo que, se repitirmos nossos experimentos 100 vezes, 95 deles estarão dentro do intervalo predeterminado.
Coletando as médias e o desvio padrão.
dicionario_metricas = {
'MAE': {'Média': 36.8409, 'Desvio Padrão': 0.6424},
'MSE': {'Média': 2294.2634, 'Desvio Padrão': 86.8002},
'RMSE': {'Média': 47.8899, 'Desvio Padrão': 0.9054},
'R2': {'Média': 0.6484, 'Desvio Padrão': 0.0223},
'RMSLE': {'Média': 0.1707, 'Desvio Padrão': 0.0497},
'MAPE': {'Média': 0.0765, 'Desvio Padrão': 0.0016}
}
Gerando o intervalo de confiança:
for x in dicionario_metricas:
media = dicionario_metricas[x]['Média']
sd = dicionario_metricas[x]['Desvio Padrão']
print('O intervalo de confiança (de 95%) para {} é de {} até {}'.format(x, round(media - 1.96*sd, 5), round(media + 1.96*sd, 5)))
O intervalo de confiança (de 95%) para MAE é de 35.5818 até 38.1 O intervalo de confiança (de 95%) para MSE é de 2124.13501 até 2464.39179 O intervalo de confiança (de 95%) para RMSE é de 46.11532 até 49.66448 O intervalo de confiança (de 95%) para R2 é de 0.60469 até 0.69211 O intervalo de confiança (de 95%) para RMSLE é de 0.07329 até 0.26811 O intervalo de confiança (de 95%) para MAPE é de 0.07336 até 0.07964
Conferindo com o treino se o intervalo corresponde:
predict_model(xgboost)
| Model | MAE | MSE | RMSE | R2 | RMSLE | MAPE | |
|---|---|---|---|---|---|---|---|
| 0 | Extreme Gradient Boosting Regressor | 37.1792 | 2283.4721 | 47.7857 | 0.6488 | 0.1102 | 0.078 |
| NU_NOTA_MT | NU_NOTA_LC | NU_NOTA_CN | NU_NOTA_CH | Label | |
|---|---|---|---|---|---|
| 0 | 480.3 | 530.5 | 507.2 | 525.0 | 512.588623 |
| 1 | 810.9 | 627.5 | 628.0 | 661.0 | 654.039612 |
| 2 | 515.1 | 562.9 | 448.6 | 558.2 | 528.294678 |
| 3 | 552.0 | 567.2 | 475.0 | 541.5 | 537.178406 |
| 4 | 662.1 | 607.3 | 538.0 | 598.5 | 594.691406 |
| ... | ... | ... | ... | ... | ... |
| 6658 | 432.7 | 457.8 | 445.4 | 426.8 | 443.105408 |
| 6659 | 406.8 | 361.5 | 421.3 | 340.6 | 398.012207 |
| 6660 | 597.6 | 558.6 | 508.8 | 483.2 | 542.178223 |
| 6661 | 485.7 | 580.6 | 448.4 | 596.9 | 549.689209 |
| 6662 | 496.4 | 493.8 | 407.0 | 491.0 | 456.757294 |
6663 rows × 5 columns
De fato, todos as métricas estão dentro do intervalo de confiança.
Como podemos interpretar as variáveis?
No gráfico a seguir, é possível visualizar que há uma coerência entre as cores. Como podemos interpretá-lo? Basta identificar onde há o 0 no gráfico. A direita desse zero, ressalta que quanto mais a direita mais influente será a variável. A esquerda desse zero, ressalta que quanto mais a esquerda menos influente será a variável. E com relação a cor, quanto mais rosa, maior será o valor correspondente.
Por exemplo, no caso, a nota em Linguagens e Códigos é a que mais influencia, e de forma proporcional. Quanto maior a nota em linguagens, maior será a nota em ciências humanas. O mesmo acontece com as outras, mas de forma menos influente (estão mais perto do zero).
interpret_model(xgboost)
Podemos visualizar a importância de cada variável de acordo com o seguinte gráfico:
plot_model(xgboost, 'feature')
Concluímos que, quanto maior a linguagens do candidato em Linguagens, maior será sua nota em Ciências Humanas. Esse efeito pode ser por causa das duas provas serem no mesmo dia, em que o candidado possa ter se preparado de forma mais sutil e delicada, não tendo uma referência de um dia de prova anterior.

Fonte: https://slideplayer.com.br/slide/9174515/27/images/9/Modelo+de+Regress%C3%A3o+Linear+Simples.jpg
Um modelo de regressão tenta ajudar uma linha de tendência nos valores para que seja o mais próximo possível do real. No gráfico da imagem acima, perceba que os pontos amarelos são os valores reais. A reta linear é uma reta que analisa a tendência e os possível valores mais próximos desses pontos dita uma inclinação. Os pontos dessa reta são os que o modelo irá prever de acordo com o valor em X. A distância entre o ponto real e a reta é chamada de Erro Aleatório, ou resíduos.
Como repassado na seção de métricas, o R quadrado é influenciado pelos resíduos, pelos valores previstos, entre outros. Quanto maior o R², melhor o modelo estará performando. Entretanto, é necessária a avaliação de outras métricas para que não haja um enviesamento em interpretar somente essa variável.
plot_model(xgboost, plot='error')
64,9% da variância de nossos dados podem ser explicados pelo modelo construído, enquanto os outros 35,1%, teoricamente, se tratariam de uma variância residual. (observando os dados de teste).
Para o gráfico a seguir, iremos analisar a variação dos resíduos e a distribuição deles. Para um modelo coerente, o ideal é que os modelos estejam normalmente distribuídos.
plot_model(xgboost, plot='residuals')
De fato o modelo atende a algumas características da regressão linear, onde estão variados e normalmente distribuídos (pelo gráfico de sino demonstrado na horizontal).
Os parâmetros do modelo utilizado
plot_model(xgboost, plot='parameter')
| Parameters | |
|---|---|
| base_score | 0.5 |
| booster | gbtree |
| colsample_bylevel | 1 |
| colsample_bynode | 1 |
| colsample_bytree | 1 |
| gamma | 0 |
| importance_type | gain |
| learning_rate | 0.1 |
| max_delta_step | 0 |
| max_depth | 3 |
| min_child_weight | 1 |
| missing | None |
| n_estimators | 100 |
| n_jobs | -1 |
| nthread | None |
| objective | reg:linear |
| random_state | 1234 |
| reg_alpha | 0 |
| reg_lambda | 1 |
| scale_pos_weight | 1 |
| seed | None |
| silent | None |
| subsample | 1 |
| verbosity | 0 |
De fato o nosso modelo pode explicar algumas coisas. Com ele podemos prever um valor em que, em média, pode estar apenas 7,65% distante do valor real.
Há de se considerar esse valor, em que o modelo possa explicar de forma razoável a nota de Ciências Humanas de um candidato. Seu objetivo é ficar nos 0%, mas seu cenário é utópico.
64,9% da variância de nossos dados podem ser explicados pelo modelo construído, assim possibilitando uma aproximação maior do real.
Em relação à todos os modelos testados, o nosso modelo gerou uma melhora em 64,94% na métrica MSE, em comparação com o modelo Lasso Least Angle Regression. É o melhor modelo que se desempenha em toda a bateria de testes.
Também podemos concluir que, a nota de Linguagens e Códigos dos candidatos influencia diretamente na nota de Ciências Humanas. Podemos concluir que, há uma correlação forte entre Linguagens e Humanas.
Finalizando o modelo
modelo_finalizado = finalize_model(xgboost)
save_model(modelo_finalizado, 'ciencias_humanas_ml')
Transformation Pipeline and Model Succesfully Saved
Carregando o modelo para testes
loaded_model = load_model('ciencias_humanas_ml')
Transformation Pipeline and Model Successfully Loaded
Validando o modelo
previsoes = predict_model(loaded_model, data=validation)
previsoes
| NU_NOTA_MT | NU_NOTA_CH | NU_NOTA_LC | NU_NOTA_CN | Label | |
|---|---|---|---|---|---|
| index | |||||
| 18352 | 479.0 | 485.8 | 493.2 | 407.9 | 452.585388 |
| 43950 | 375.6 | 514.1 | 506.5 | 370.1 | 457.920685 |
| 3805 | 634.1 | 584.5 | 565.1 | 521.4 | 557.407288 |
| 86575 | 538.3 | 461.2 | 464.6 | 496.2 | 463.143890 |
| 120366 | 469.3 | 483.8 | 527.4 | 500.0 | 511.079193 |
| ... | ... | ... | ... | ... | ... |
| 11081 | 469.5 | 481.1 | 488.2 | 353.0 | 446.166107 |
| 31487 | 460.8 | 545.3 | 502.2 | 472.8 | 475.738007 |
| 64752 | 509.4 | 556.4 | 493.8 | 495.9 | 478.067810 |
| 55090 | 471.2 | 540.7 | 436.2 | 471.7 | 438.088898 |
| 71240 | 413.6 | 408.1 | 457.3 | 347.8 | 429.068787 |
18508 rows × 5 columns
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_squared_error
from math import sqrt
def rmsle(y_pred, y_test) :
assert len(y_test) == len(y_pred)
return np.sqrt(np.mean((np.log(1+y_pred) - np.log(1+y_test))**2))
def mape_vectorized_v2(a, b):
mask = a != 0
return (np.fabs(a - b)/a)[mask].mean()
rmse = sqrt(mean_squared_error(previsoes['NU_NOTA_CH'], previsoes['Label']))
print('MSE {}'.format(mean_squared_error(previsoes['NU_NOTA_CH'], previsoes['Label'])))
print('MAE {}'.format(mean_absolute_error(previsoes['NU_NOTA_CH'], previsoes['Label'])))
print('RMSE {}'.format(rmse))
print('MAPE {}'.format(mape_vectorized_v2(previsoes['NU_NOTA_CH'], previsoes['Label'])))
print('RMSLE {}'.format(rmsle(previsoes['Label'],previsoes['NU_NOTA_CH'])))
MSE 2292.4993514762446 MAE 37.06303357822426 RMSE 47.88005170711749 MAPE 0.07685896038886238 RMSLE 0.1745296605343267
Todas as métricas estão dentro dos intervalos determinados nesta seção.
Agradeço primordialmente a Alura por proporcionar essa esperiência incrível!
Foram dias analisando, criando hipóteses e explorando o universo de DataScience. Foi um grande aprendizado.